diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2c1db067 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +debug/ +Exe/ +release/ +COPY.txt +*.scb +*.suo +build/ +*.sdf +*.opensdf +ipch/ \ No newline at end of file diff --git a/examples/core/4square.xml b/examples/core/4square.xml new file mode 100644 index 00000000..59a12363 --- /dev/null +++ b/examples/core/4square.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/4square/4squareB.xml b/examples/core/4square/4squareB.xml new file mode 100644 index 00000000..ef8db5f8 --- /dev/null +++ b/examples/core/4square/4squareB.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/4square/4squareS.xml b/examples/core/4square/4squareS.xml new file mode 100644 index 00000000..af5deea8 --- /dev/null +++ b/examples/core/4square/4squareS.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/4square/4squareV.xml b/examples/core/4square/4squareV.xml new file mode 100644 index 00000000..a7f4f1d5 --- /dev/null +++ b/examples/core/4square/4squareV.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/core/boolean.xml b/examples/core/boolean.xml new file mode 100644 index 00000000..d5209d9a --- /dev/null +++ b/examples/core/boolean.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/boolean/booleanB.xml b/examples/core/boolean/booleanB.xml new file mode 100644 index 00000000..e1201ac6 --- /dev/null +++ b/examples/core/boolean/booleanB.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + Walk to the action box + + + + + Walk to the action box + + + + + + Walk the slow direction + + + + + Walk the fast direction + + + + + + + + + + First of two transitions out of ChangeSpeed + If I've reached the goal AND the timer has NOT reached at least 10 seconds, transition to fast + + + + + + + + + Second transtion out of ChangeSpeed + - it is evaluated after the previous (because it is defined second). + - If the previous condition was NOT met, it is either because the goal wasn't reached, or it + wasn't reached fast enough. + - If it was a case of timing, this condition will be met (at goal), the agent will be filtered + in the slow direction. + + + + + + + + + \ No newline at end of file diff --git a/examples/core/boolean/booleanS.xml b/examples/core/boolean/booleanS.xml new file mode 100644 index 00000000..65c484c3 --- /dev/null +++ b/examples/core/boolean/booleanS.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/boolean/booleanV.xml b/examples/core/boolean/booleanV.xml new file mode 100644 index 00000000..54de25aa --- /dev/null +++ b/examples/core/boolean/booleanV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/core/bottleneck.xml b/examples/core/bottleneck.xml new file mode 100644 index 00000000..906d810d --- /dev/null +++ b/examples/core/bottleneck.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/bottleneck/bottleneckB.xml b/examples/core/bottleneck/bottleneckB.xml new file mode 100644 index 00000000..59098d76 --- /dev/null +++ b/examples/core/bottleneck/bottleneckB.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/bottleneck/bottleneckMap.txt b/examples/core/bottleneck/bottleneckMap.txt new file mode 100644 index 00000000..1e9bbec1 --- /dev/null +++ b/examples/core/bottleneck/bottleneckMap.txt @@ -0,0 +1,18 @@ +6 +4 -0.5 -3.0 +4 0.5 -3.0 +4 -0.5 3.0 +4 0.5 3.0 +2 1.0 -6 +2 1.0 6 +10 +0 1 +0 2 +0 3 +1 2 +1 3 +2 3 +0 4 +1 4 +2 5 +3 5 diff --git a/examples/core/bottleneck/bottleneckS.xml b/examples/core/bottleneck/bottleneckS.xml new file mode 100644 index 00000000..c77fe48c --- /dev/null +++ b/examples/core/bottleneck/bottleneckS.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/bottleneck/bottleneckV.xml b/examples/core/bottleneck/bottleneckV.xml new file mode 100644 index 00000000..208823d5 --- /dev/null +++ b/examples/core/bottleneck/bottleneckV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/circle.xml b/examples/core/circle.xml new file mode 100644 index 00000000..e12ef2be --- /dev/null +++ b/examples/core/circle.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/circle/circleB.xml b/examples/core/circle/circleB.xml new file mode 100644 index 00000000..67f362b9 --- /dev/null +++ b/examples/core/circle/circleB.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/circle/circleS.xml b/examples/core/circle/circleS.xml new file mode 100644 index 00000000..62ce7447 --- /dev/null +++ b/examples/core/circle/circleS.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/circle/circleV.xml b/examples/core/circle/circleV.xml new file mode 100644 index 00000000..bbc8a990 --- /dev/null +++ b/examples/core/circle/circleV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/concave.xml b/examples/core/concave.xml new file mode 100644 index 00000000..b5b20c4b --- /dev/null +++ b/examples/core/concave.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/concave/concaveMapB.xml b/examples/core/concave/concaveMapB.xml new file mode 100644 index 00000000..cd15ab44 --- /dev/null +++ b/examples/core/concave/concaveMapB.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/concave/concaveRM.txt b/examples/core/concave/concaveRM.txt new file mode 100644 index 00000000..be2e6fcd --- /dev/null +++ b/examples/core/concave/concaveRM.txt @@ -0,0 +1,24 @@ +9 +3 0.133494 4.792672 +3 0.315699 -1.265646 +3 5.964055 5.931454 +3 -7.610221 5.248185 +2 -10.571053 0.328648 +2 10.792489 0.419751 +3 5.235235 -6.959554 +2 0.270147 -8.781604 +3 -6.243683 -6.777349 +12 +1 0 +2 1 +2 0 +3 0 +4 3 +5 2 +3 1 +6 5 +7 6 +8 7 +8 4 +8 6 + diff --git a/examples/core/concave/concaveS.xml b/examples/core/concave/concaveS.xml new file mode 100644 index 00000000..3c031aae --- /dev/null +++ b/examples/core/concave/concaveS.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/concave/concaveV.xml b/examples/core/concave/concaveV.xml new file mode 100644 index 00000000..1bc1ed65 --- /dev/null +++ b/examples/core/concave/concaveV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/cross.xml b/examples/core/cross.xml new file mode 100644 index 00000000..6f510939 --- /dev/null +++ b/examples/core/cross.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/cross/crossB.xml b/examples/core/cross/crossB.xml new file mode 100644 index 00000000..4cb39945 --- /dev/null +++ b/examples/core/cross/crossB.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/cross/crossS.xml b/examples/core/cross/crossS.xml new file mode 100644 index 00000000..c085e55a --- /dev/null +++ b/examples/core/cross/crossS.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/cross/crossV.xml b/examples/core/cross/crossV.xml new file mode 100644 index 00000000..71d86485 --- /dev/null +++ b/examples/core/cross/crossV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/event.xml b/examples/core/event.xml new file mode 100644 index 00000000..7aa2ad3b --- /dev/null +++ b/examples/core/event.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/event/eventB.xml b/examples/core/event/eventB.xml new file mode 100644 index 00000000..68103f56 --- /dev/null +++ b/examples/core/event/eventB.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/event/eventS.xml b/examples/core/event/eventS.xml new file mode 100644 index 00000000..ea486eab --- /dev/null +++ b/examples/core/event/eventS.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/event/eventV.xml b/examples/core/event/eventV.xml new file mode 100644 index 00000000..9594c480 --- /dev/null +++ b/examples/core/event/eventV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/globalNavSwap-navmesh.xml b/examples/core/globalNavSwap-navmesh.xml new file mode 100644 index 00000000..14cd8678 --- /dev/null +++ b/examples/core/globalNavSwap-navmesh.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/globalNavSwap-roadmap.xml b/examples/core/globalNavSwap-roadmap.xml new file mode 100644 index 00000000..71e8930b --- /dev/null +++ b/examples/core/globalNavSwap-roadmap.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/globalNavSwap-vectorfield.xml b/examples/core/globalNavSwap-vectorfield.xml new file mode 100644 index 00000000..1b115a34 --- /dev/null +++ b/examples/core/globalNavSwap-vectorfield.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/globalNavSwap/fieldM-Small.txt b/examples/core/globalNavSwap/fieldM-Small.txt new file mode 100644 index 00000000..fc90308a --- /dev/null +++ b/examples/core/globalNavSwap/fieldM-Small.txt @@ -0,0 +1,10003 @@ +100 100 +0.5 +-25.0 -25.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000301596883219 +0.999999880791 0.0004377864243 +0.999999821186 0.000625617278274 +0.999999582767 0.000880167004652 +0.999999284744 0.001219072612 +0.999998629093 0.0016622702824 +0.999997496605 0.00223140977323 +0.999995648861 0.00294891162775 +0.999992668629 0.00383660197258 +0.999987900257 0.00491398014128 +0.999980807304 0.0061961254105 +0.999970376492 0.00769142899662 +0.999955832958 0.00939925294369 +0.999936044216 0.0113078439608 +0.99991029501 0.0133926933631 +0.999877989292 0.01561564859 +0.999839305878 0.0179250147194 +0.999794781208 0.020256800577 +0.999746024609 0.0225371252745 +0.999695181847 0.0246859043837 +0.999645531178 0.0266211945564 +0.999600410461 0.0282644052058 +0.999563455582 0.0295455250889 +0.999537587166 0.0304079074413 +0.9995251894 0.030812561512 +0.999527335167 0.0307409130037 +0.999543964863 0.0301962718368 +0.999573469162 0.0292035341263 +0.999613285065 0.027807334438 +0.999660074711 0.0260688252747 +0.99971050024 0.0240611024201 +0.999760866165 0.021864335984 +0.99980866909 0.0195604022592 +0.99985152483 0.017227968201 +0.999888420105 0.0149382902309 +0.999918699265 0.012751868926 +0.999942600727 0.0107164299116 +0.999960660934 0.0088659953326 +0.999973893166 0.00722112134099 +0.99998319149 0.00579004036263 +0.999989569187 0.0045704417862 +0.999993622303 0.00355169270188 +0.999996244907 0.00271715619601 +0.999997913837 0.00204643141478 +0.999998867512 0.00151734531391 +0.999999344349 0.0011075878283 +0.999999701977 0.000795939064119 +0.999999761581 0.000563105742913 +0.999999940395 0.000392202200601 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999880791 0.000438082555775 +0.999999821186 0.000635897857137 +0.999999523163 0.00090871588327 +0.999999165535 0.00127842917573 +0.999998390675 0.00177064375021 +0.999997079372 0.00241429475136 +0.999994754791 0.00324079184793 +0.999990820885 0.00428264355287 +0.999984502792 0.00557147525251 +0.999974548817 0.00713549554348 +0.999959528446 0.00899647176266 +0.999937653542 0.0111663956195 +0.99990683794 0.0136441430077 +0.999865293503 0.0164124313742 +0.999811112881 0.0194354690611 +0.999743282795 0.0226577017456 +0.99966186285 0.0260040126741 +0.999568283558 0.029381563887 +0.999465703964 0.032683365047 +0.999359190464 0.0357935652137 +0.999255001545 0.0385937802494 +0.999160349369 0.0409707091749 +0.999082684517 0.0428233556449 +0.999028384686 0.044070251286 +0.99900239706 0.0446552745998 +0.999007105827 0.0445516854525 +0.99904191494 0.0437642708421 +0.999103724957 0.0423288345337 +0.999187231064 0.0403096266091 +0.999285519123 0.0377946570516 +0.999391138554 0.0348893292248 +0.999497115612 0.0317093320191 +0.999597430229 0.0283729825169 +0.999687552452 0.0249941069633 +0.99976503849 0.0216759741306 +0.999828696251 0.0185063760728 +0.999879002571 0.0155547102913 +0.999917149544 0.0128705501556 +0.999945044518 0.0104839541018 +0.999964654446 0.00840709079057 +0.999978005886 0.00663681188598 +0.999986708164 0.00515783438459 +0.999992132187 0.00394613528624 +0.999995529652 0.00297217466868 +0.99999755621 0.00220382632688 +0.999998688698 0.00160873075947 +0.999999344349 0.00115609623026 +0.999999642372 0.000817920314148 +0.999999761581 0.000569687166717 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999821186 0.00062646396691 +0.999999523163 0.000909331836738 +0.99999910593 0.00129943736829 +0.99999833107 0.00182807329111 +0.999996781349 0.00253182766028 +0.999994039536 0.00345203047618 +0.999989271164 0.00463353283703 +0.999981284142 0.00612270180136 +0.999968290329 0.00796460732818 +0.999947965145 0.0101993586868 +0.999917328358 0.0128577845171 +0.999872624874 0.0159566756338 +0.999809980392 0.0194940175861 +0.999725162983 0.0234446302056 +0.999614655972 0.0277569498867 +0.99947655201 0.0323512367904 +0.999310791492 0.0371199958026 +0.999120533466 0.0419306978583 +0.998912155628 0.0466309562325 +0.998695790768 0.0510560385883 +0.998484253883 0.0550381578505 +0.998292267323 0.0584167540073 +0.998134791851 0.0610491335392 +0.998024761677 0.0628203824162 +0.99797219038 0.0636512413621 +0.997981488705 0.0635041296482 +0.998052120209 0.0623857565224 +0.998177468777 0.0603465624154 +0.998346805573 0.0574772134423 +0.998546183109 0.0539019145072 +0.998760700226 0.0497697852552 +0.998975932598 0.0452446304262 +0.999179780483 0.0404944121838 +0.99936324358 0.0356810763478 +0.999520897865 0.0309517104179 +0.999650597572 0.0264318156987 +0.999753117561 0.022220749408 +0.999830842018 0.0183897335082 +0.999887764454 0.0149821825325 +0.999927818775 0.0120159229264 +0.999954938889 0.0094868671149 +0.999972820282 0.00737349735573 +0.999984025955 0.00564173329622 +0.999990999699 0.00424955226481 +0.999995052814 0.0031511427369 +0.999997377396 0.00230033369735 +0.999998569489 0.00165315717459 +0.999999344349 0.00116960995365 +0.999999642372 0.000814654980786 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999523163 0.000881956308149 +0.999999165535 0.00128016422968 +0.99999833107 0.00182931381278 +0.99999666214 0.00257342867553 +0.999993562698 0.00356396846473 +0.99998819828 0.0048590307124 +0.999978721142 0.00652161100879 +0.999962866306 0.00861678179353 +0.9999371171 0.0112076709047 +0.999897003174 0.0143503090367 +0.999836325645 0.0180875249207 +0.999748170376 0.0224422384053 +0.999624252319 0.0274107605219 +0.999456763268 0.0329567752779 +0.999238967896 0.0390068553388 +0.998966634274 0.0454481467605 +0.998640358448 0.0521291196346 +0.998266041279 0.0588635802269 +0.997856616974 0.0654381662607 +0.997431695461 0.0716229379177 +0.997016847134 0.077184394002 +0.996640563011 0.0818998217583 +0.996331989765 0.0855717509985 +0.996116757393 0.0880414173007 +0.996013760567 0.0891995951533 +0.996032059193 0.088994577527 +0.99617010355 0.0874354913831 +0.996415674686 0.0845918953419 +0.996747434139 0.0805888399482 +0.9971383214 0.0755979567766 +0.997559130192 0.0698256641626 +0.997981786728 0.0634995475411 +0.998382508755 0.0568535029888 +0.998743534088 0.0501137413085 +0.999054014683 0.0434864647686 +0.999309778214 0.0371481589973 +0.999511957169 0.0312389917672 +0.999665558338 0.0258599575609 +0.999777853489 0.0210730228573 +0.999857068062 0.0169041845948 +0.999910891056 0.0133484601974 +0.999946177006 0.0103762615472 +0.999968409538 0.00794013310224 +0.999982059002 0.00598131073639 +0.999990165234 0.00443558720872 +0.999994754791 0.00323814782314 +0.999997317791 0.00232722028159 +0.999998569489 0.00164655898698 +0.999999284744 0.00114688382018 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99999922514 0.00122238311451 +0.999998390675 0.00177425320726 +0.999996781349 0.0025352712255 +0.999993622303 0.00356639432721 +0.999987781048 0.00493884831667 +0.999977350235 0.00673299329355 +0.999959170818 0.00903587881476 +0.999928772449 0.0119372783229 +0.999879479408 0.0155241070315 +0.999802529812 0.0198731888086 +0.999686360359 0.0250427797437 +0.999517381191 0.031063247472 +0.999280452728 0.0379278659821 +0.998960494995 0.0455845631659 +0.998544752598 0.0539298914373 +0.998025715351 0.0628061890602 +0.997404336929 0.0720029324293 +0.996692717075 0.0812627598643 +0.995915293694 0.0902921631932 +0.995109677315 0.0987763181329 +0.994323730469 0.106396906078 +0.993611812592 0.112851724029 +0.993028581142 0.11787392199 +0.992622077465 0.121249616146 +0.9924274683 0.122832149267 +0.992462098598 0.122551992536 +0.992722809315 0.120421558619 +0.99318665266 0.116534136236 +0.993813931942 0.11105773598 +0.994553864002 0.104223869741 +0.995351195335 0.0963118597865 +0.996152937412 0.0876308605075 +0.996914029121 0.0785000398755 +0.997600674629 0.0692297145724 +0.998192131519 0.0601039044559 +0.998679876328 0.0513668730855 +0.999065876007 0.043213699013 +0.999359488487 0.0357857570052 +0.999574422836 0.0291706752032 +0.999726057053 0.0234061609954 +0.999829053879 0.0184869263321 +0.999896705151 0.0143732344732 +0.999939501286 0.0110003361478 +0.999965667725 0.00828754156828 +0.999981045723 0.00614639697596 +0.999989926815 0.00448742182925 +0.999994754791 0.00322523387149 +0.999997377396 0.00228201318532 +0.999998748302 0.00158954493236 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999998629093 0.0016679209657 +0.999997079372 0.00242086499929 +0.999994039536 0.00345908245072 +0.999988138676 0.00486565101892 +0.99997729063 0.00673758471385 +0.999957799911 0.00918422266841 +0.999924063683 0.0123238759115 +0.999867498875 0.0162783060223 +0.999776005745 0.0211650170386 +0.999633073807 0.0270872954279 +0.999417662621 0.0341225489974 +0.999104559422 0.0423096492887 +0.998665928841 0.0516363121569 +0.998074412346 0.0620280615985 +0.99730694294 0.0733405426145 +0.996350467205 0.0853560194373 +0.995207428932 0.097786128521 +0.993900477886 0.110280901194 +0.992475450039 0.122443787754 +0.99100124836 0.133852526546 +0.989565551281 0.144083142281 +0.988267064095 0.152735829353 +0.987204372883 0.159459605813 +0.986464500427 0.163974836469 +0.986110508442 0.166090369225 +0.986173450947 0.165715932846 +0.986647903919 0.162867516279 +0.987492382526 0.157666623592 +0.988635540009 0.150332227349 +0.989985704422 0.141167551279 +0.991442978382 0.130540594459 +0.992910861969 0.118861109018 +0.99430680275 0.106555253267 +0.995568394661 0.0940400436521 +0.996656894684 0.0816999226809 +0.997556209564 0.0698678046465 +0.998269081116 0.0588115528226 +0.99881207943 0.0487269051373 +0.999210178852 0.0397367142141 +0.999491155148 0.0318958200514 +0.999682426453 0.0251999236643 +0.999807953835 0.0195973049849 +0.999887466431 0.0150014692917 +0.999936103821 0.0113037172705 +0.99996483326 0.00838434603065 +0.999981284142 0.00612190132961 +0.999990344048 0.00440028868616 +0.999995172024 0.00311358482577 +0.999997675419 0.00216886214912 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999997496605 0.00224052648991 +0.999994695187 0.00325183197856 +0.999989151955 0.00464616855606 +0.999978601933 0.00653495732695 +0.999959051609 0.009048207663 +0.999923944473 0.0123322885484 +0.999863088131 0.0165452770889 +0.999761283398 0.0218494385481 +0.999596595764 0.0284006614238 +0.999339640141 0.0363349281251 +0.998952805996 0.0457525067031 +0.998391211033 0.0567007996142 +0.997605741024 0.069157473743 +0.996548116207 0.0830162465572 +0.995178818703 0.0980768203735 +0.993475914001 0.114041738212 +0.991445481777 0.130521252751 +0.9891294837 0.147046923637 +0.986610591412 0.163093537092 +0.984011054039 0.17810715735 +0.981485188007 0.191537827253 +0.979205310345 0.20287181437 +0.977342665195 0.211662828922 +0.976047337055 0.217557996511 +0.975428164005 0.220317691565 +0.975538313389 0.219829395413 +0.976368367672 0.216112956405 +0.977847218513 0.209320023656 +0.979851841927 0.19972576201 +0.982223808765 0.187713488936 +0.984789252281 0.173752591014 +0.987379670143 0.158371120691 +0.989848911762 0.142123684287 +0.992086112499 0.125558853149 +0.994021177292 0.109187491238 +0.995623290539 0.0934564843774 +0.996895968914 0.0787290036678 +0.997867405415 0.0652735009789 +0.998580515385 0.0532614290714 +0.999084830284 0.0427726656199 +0.999428391457 0.0338070057333 +0.999654114246 0.026299353689 +0.999797224998 0.0201370492578 +0.999884784222 0.0151765309274 +0.999936640263 0.0112587269396 +0.999966204166 0.00822165049613 +0.999982535839 0.0059100817889 +0.999991238117 0.0041821799241 +0.999995708466 0.00291336746886 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.000162561016623 +0.999994814396 0.00319987209514 +0.999989211559 0.00464033195749 +0.999978005886 0.00662433542311 +0.999956667423 0.00930894259363 +0.999917089939 0.0128768160939 +0.999846279621 0.01753276214 +0.999723851681 0.0234966613352 +0.999519586563 0.0309923663735 +0.999190330505 0.0402320958674 +0.998678267002 0.0513969399035 +0.997910320759 0.0646139606833 +0.996800243855 0.0799319669604 +0.995255172253 0.0972985252738 +0.993185818195 0.116541035473 +0.990521788597 0.137355580926 +0.98722922802 0.159305736423 +0.983329117298 0.181834518909 +0.978910803795 0.204287797213 +0.974139094353 0.225948944688 +0.969249427319 0.246080264449 +0.964531898499 0.263966143131 +0.960304141045 0.278954923153 +0.956877052784 0.290492922068 +0.954518318176 0.29815196991 +0.953419446945 0.301647543907 +0.953671693802 0.300849348307 +0.955254018307 0.295786768198 +0.95803630352 0.286646872759 +0.961795568466 0.273768723011 +0.966243863106 0.257629275322 +0.971063256264 0.238822355866 +0.975942254066 0.218028768897 +0.980608224869 0.195978119969 +0.984850347042 0.173406526446 +0.988531708717 0.1510130018 +0.991589784622 0.129419758916 +0.994026184082 0.109141714871 +0.995890319347 0.0905666202307 +0.997261941433 0.0739488229156 +0.998233437538 0.0594141297042 +0.998896062374 0.0469742119312 +0.999331772327 0.0365478359163 +0.999608278275 0.0279846470803 +0.99977761507 0.02108906582 +0.999877631664 0.0156421400607 +0.999934732914 0.0114197619259 +0.999966323376 0.00820651464164 +0.999983072281 0.00580519856885 +0.999991714954 0.00404244940728 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.000235003215494 +0.999991118908 0.00419983686879 +0.999981403351 0.00608950201422 +0.999962151051 0.00869149621576 +0.999925434589 0.0122111085802 +0.999857366085 0.0168866589665 +0.999735713005 0.0229846108705 +0.999525904655 0.0307899303734 +0.999175846577 0.0405908413231 +0.998612582684 0.052657790482 +0.997738301754 0.0672169178724 +0.996430277824 0.0844194889069 +0.994544863701 0.104309745133 +0.991928875446 0.126795098186 +0.988438427448 0.151622906327 +0.983963549137 0.178368881345 +0.978459000587 0.206440851092 +0.971971273422 0.235099464655 +0.964660406113 0.263496130705 +0.956807136536 0.290723145008 +0.948802649975 0.315869450569 +0.941118836403 0.338075935841 +0.934264063835 0.356581538916 +0.928729593754 0.370757818222 +0.924932718277 0.380130767822 +0.923170208931 0.384391397238 +0.92358225584 0.383400261402 +0.926136374474 0.377188801765 +0.930631101131 0.365958690643 +0.936719357967 0.350080966949 +0.943949639797 0.330089390278 +0.951817214489 0.306665629148 +0.959820747375 0.280613869429 +0.967513203621 0.252820521593 +0.97454226017 0.22420398891 +0.980672240257 0.195657774806 +0.985787630081 0.167996048927 +0.989879906178 0.141907021403 +0.993022859097 0.117921218276 +0.99534291029 0.0963973626494 +0.996990442276 0.0775246918201 +0.998116850853 0.0613399408758 +0.998859107494 0.047753777355 +0.999330639839 0.0365820154548 +0.999619662762 0.0275776199996 +0.999790668488 0.0204600691795 +0.999888300896 0.0149398772046 +0.999942302704 0.0107374805957 +0.999971091747 0.00759616261348 +0.999985992908 0.00528981490061 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000334461365128 +0.999985277653 0.00543105229735 +0.99996650219 0.00818457826972 +0.999931693077 0.0116868009791 +0.999865055084 0.016425376758 +0.999741792679 0.0227208919823 +0.999521493912 0.0309307444841 +0.999141156673 0.0414351560175 +0.998507380486 0.0546152219176 +0.99748891592 0.0708225816488 +0.995910763741 0.0903415456414 +0.993555605412 0.113345608115 +0.99017226696 0.139852955937 +0.985498011112 0.169686302543 +0.97929340601 0.20244550705 +0.97138774395 0.237499013543 +0.961729586124 0.274000406265 +0.950432181358 0.310931801796 +0.937802493572 0.347169101238 +0.924343883991 0.38156029582 +0.910728871822 0.413004815578 +0.897743046284 0.440519362688 +0.886210083961 0.463283449411 +0.876907110214 0.480659902096 +0.870484948158 0.492194890976 +0.86740309 0.497606039047 +0.867883861065 0.496767163277 +0.871891081333 0.489699751139 +0.879134356976 0.476573586464 +0.889097392559 0.457718044519 +0.901088058949 0.433635830879 +0.914310634136 0.405013471842 +0.927945494652 0.372715979815 +0.941232442856 0.337759494781 +0.953541457653 0.301261812449 +0.96442091465 0.264371216297 +0.973617196083 0.228187516332 +0.981063306332 0.193686425686 +0.9868465662 0.161659449339 +0.991159260273 0.132677718997 +0.994250178337 0.107081860304 +0.996381163597 0.0849960297346 +0.997795760632 0.0663587376475 +0.998700380325 0.0509648621082 +0.999258220196 0.0385098047554 +0.999589979649 0.0286319553852 +0.999780535698 0.0209486372769 +0.999886214733 0.0150843355805 +0.999942779541 0.0106904711574 +0.999972105026 0.00745755247772 +0.999999880791 0.000448221835541 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999880791 0.000468632060802 +0.999976038933 0.00692017609254 +0.999945104122 0.0104793887585 +0.999887883663 0.0149607043713 +0.999779045582 0.0210211519152 +0.999577403069 0.0290676392615 +0.999217510223 0.0395515188575 +0.998597085476 0.052949283272 +0.997565746307 0.0697323009372 +0.995912253857 0.0903254896402 +0.993358969688 0.115055881441 +0.989563822746 0.144094288349 +0.98413926363 0.177397042513 +0.976689577103 0.214656710625 +0.96686899662 0.255272716284 +0.954455316067 0.298353642225 +0.939424574375 0.342755496502 +0.922013103962 0.38715839386 +0.902748227119 0.430169284344 +0.882434844971 0.470434486866 +0.862099230289 0.506739377975 +0.842894554138 0.538078725338 +0.825988411903 0.563687086105 +0.812450230122 0.58303052187 +0.803153574467 0.595771968365 +0.798702836037 0.601725637913 +0.799387097359 0.600816249847 +0.805159389973 0.593058466911 +0.815640568733 0.578558981419 +0.83014780283 0.55754339695 +0.847748279572 0.530398726463 +0.86733931303 0.497717142105 +0.88775062561 0.460324734449 +0.907856523991 0.419280916452 +0.926685392857 0.375837802887 +0.943503379822 0.3313626647 +0.957860589027 0.287233531475 +0.969591498375 0.244728848338 +0.978776454926 0.204930379987 +0.985674858093 0.16865645349 +0.990649402142 0.136432096362 +0.994096875191 0.10849583149 +0.996395051479 0.0848341062665 +0.997869968414 0.0652334392071 +0.998781979084 0.0493391342461 +0.999325752258 0.036711871624 +0.999638676643 0.026876905933 +0.999812483788 0.0193626787513 +0.999905765057 0.0137281343341 +0.999954044819 0.00957979355007 +0.999999761581 0.000648086192086 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999761581 0.000646445085295 +0.99996227026 0.00868887640536 +0.999912381172 0.0132290897891 +0.999821662903 0.0188818089664 +0.999648213387 0.0265219882131 +0.999327838421 0.0366576053202 +0.998756766319 0.049848575145 +0.997774362564 0.0666798055172 +0.996145188808 0.0877196639776 +0.993542134762 0.113463617861 +0.989539146423 0.144264236093 +0.983620107174 0.180253878236 +0.975212752819 0.221269354224 +0.963753581047 0.266793847084 +0.948781728745 0.315932363272 +0.930048823357 0.36743581295 +0.907625436783 0.419780522585 +0.881974637508 0.471296697855 +0.853968858719 0.520324110985 +0.824840426445 0.565365493298 +0.796072602272 0.605200946331 +0.769250750542 0.638946890831 +0.745908915997 0.666047930717 +0.727394521236 0.686219394207 +0.714769482613 0.699360013008 +0.70874774456 0.705462038517 +0.709663748741 0.70454031229 +0.71746224165 0.696597337723 +0.731699347496 0.681627511978 +0.751562058926 0.659662306309 +0.775907516479 0.630846560001 +0.803333878517 0.595528900623 +0.832288563251 0.554342389107 +0.861208260059 0.508252084255 +0.888670802116 0.45854562521 +0.913533806801 0.406762868166 +0.935029804707 0.35456892848 +0.952799081802 0.303601294756 +0.966856956482 0.255318701267 +0.977510988712 0.210884422064 +0.985253572464 0.171100199223 +0.990654528141 0.136394411325 +0.994274556637 0.10685519129 +0.996608018875 0.082293279469 +0.998056292534 0.0623181164265 +0.998922288418 0.0464137494564 +0.999421656132 0.034005522728 +0.999699532986 0.0245131198317 +0.999848604202 0.0173882655799 +0.999926328659 0.01213876158 +0.999999582767 0.000922535080463 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.00014445281704 +0.999999403954 0.00108822016045 +0.999938845634 0.0110510727391 +0.999857127666 0.0168896056712 +0.999709904194 0.0240814760327 +0.999428987503 0.0337865687907 +0.998911857605 0.0466368794441 +0.997993052006 0.0633213296533 +0.996419429779 0.0845468640327 +0.993822515011 0.110979571939 +0.989698708057 0.143165796995 +0.983402788639 0.181435868144 +0.974173367023 0.225801110268 +0.961197733879 0.275859713554 +0.943723261356 0.330736070871 +0.92120474577 0.389077872038 +0.893465995789 0.449130803347 +0.860831081867 0.508890628815 +0.824188828468 0.566314935684 +0.784959554672 0.619547069073 +0.744966506958 0.667101740837 +0.706240773201 0.70797175169 +0.670806050301 0.741632819176 +0.640492498875 0.767964422703 +0.616807878017 0.787113547325 +0.600872576237 0.799344778061 +0.593402683735 0.804905533791 +0.594720542431 0.803932487965 +0.604762196541 0.79640609026 +0.623080134392 0.782158017159 +0.648832201958 0.760931491852 +0.680780172348 0.732487678528 +0.717318058014 0.696745753288 +0.756554186344 0.65393102169 +0.79645472765 0.604698121548 +0.83504062891 0.550188183784 +0.870597481728 0.491995990276 +0.901854455471 0.432040005922 +0.928086936474 0.372363418341 +0.949121296406 0.314910292625 +0.96524977684 0.261329054832 +0.97708684206 0.212840646505 +0.985411942005 0.170185834169 +0.991029024124 0.133645936847 +0.994669437408 0.103114150465 +0.996938228607 0.0781932547688 +0.998299062252 0.0582976415753 +0.999085962772 0.0427450798452 +0.999524533749 0.030830334872 +0.999760448933 0.0218782331795 +0.999884724617 0.0151748964563 +0.99999910593 0.00129282625858 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.000209880061448 +0.999998867512 0.00147927214857 +0.999908268452 0.0135460663587 +0.999783098698 0.0208280496299 +0.999559283257 0.0296823568642 +0.999133467674 0.0416180901229 +0.998351275921 0.0573989823461 +0.996965229511 0.0778478309512 +0.994598984718 0.103792004287 +0.990711152554 0.135982513428 +0.984570860863 0.174985796213 +0.975261211395 0.221055209637 +0.961730420589 0.27399751544 +0.942904770374 0.333062231541 +0.917866647243 0.396888643503 +0.886071622372 0.463548213243 +0.847559392452 0.530700385571 +0.803095042706 0.5958507061 +0.754184365273 0.65666270256 +0.702943086624 0.711246013641 +0.651849687099 0.758348166943 +0.603444695473 0.797404766083 +0.560058832169 0.828452825546 +0.523625135422 0.851948618889 +0.495598971844 0.868551313877 +0.476967990398 0.878920614719 +0.468312889338 0.883562624454 +0.469875812531 0.882732510567 +0.481601715088 0.876390099525 +0.503132462502 0.864209234715 +0.533760309219 0.845635831356 +0.572360336781 0.820002198219 +0.617341578007 0.786695182323 +0.666658580303 0.745363116264 +0.717919409275 0.696126163006 +0.768596410751 0.639733970165 +0.816307544708 0.57761746645 +0.85910487175 0.51179933548 +0.895692884922 0.444673240185 +0.925517559052 0.378704458475 +0.948715746403 0.31613022089 +0.965950489044 0.258726894855 +0.978195488453 0.207685917616 +0.986526846886 0.163598999381 +0.991962850094 0.126528933644 +0.995368897915 0.0961281210184 +0.997420847416 0.0717720687389 +0.998611271381 0.0526830144227 +0.999276459217 0.0380306467414 +0.999635279179 0.0270058084279 +0.99982470274 0.0187192372978 +0.999998390675 0.00178362941369 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000300214684103 +0.999998033047 0.00198188819923 +0.999865710735 0.0163807235658 +0.999678552151 0.0253523346037 +0.999347865582 0.036108981818 +0.998719394207 0.0505904406309 +0.997567653656 0.0697035267949 +0.99553334713 0.0944102928042 +0.99207431078 0.125652372837 +0.986420333385 0.164239808917 +0.977549672127 0.210704818368 +0.964211940765 0.265132158995 +0.945026695728 0.326993137598 +0.918670296669 0.395025193691 +0.884144604206 0.467213243246 +0.841076374054 0.540916383266 +0.789964616299 0.613152325153 +0.73228520155 0.680998027325 +0.670391142368 0.742007791996 +0.607221007347 0.794532835484 +0.545891106129 0.837856054306 +0.489295065403 0.87211817503 +0.439812302589 0.898089587688 +0.399177879095 0.916873455048 +0.368506103754 0.929625332355 +0.348416924477 0.937339603901 +0.339195042849 0.940716028214 +0.340928196907 0.940089285374 +0.353579282761 0.935404479504 +0.376977354288 0.926222443581 +0.410727709532 0.911757946014 +0.454068928957 0.890966534615 +0.505718231201 0.862698674202 +0.563770413399 0.825931549072 +0.625711560249 0.78005450964 +0.688589692116 0.725151002407 +0.749336659908 0.662189185619 +0.805172920227 0.593040108681 +0.853987932205 0.520292580128 +0.894582569599 0.446902602911 +0.926711320877 0.375773757696 +0.950936615467 0.309385508299 +0.968361914158 0.249549537897 +0.980338275433 0.19732414186 +0.988216340542 0.153063386679 +0.993184566498 0.116551332176 +0.996193170547 0.0871716812253 +0.997945189476 0.0640716180205 +0.998927533627 0.0462987720966 +0.999458551407 0.0329028703272 +0.999740242958 0.0227898918092 +0.999997079372 0.00242255465128 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000422771612648 +0.999996542931 0.00261717359535 +0.999808907509 0.0195463132113 +0.999535560608 0.0304671544582 +0.999059200287 0.0433644093573 +0.998155891895 0.0607013255358 +0.996504724026 0.0835350304842 +0.993598878384 0.112965285778 +0.98868137598 0.150030165911 +0.980692625046 0.195554897189 +0.96825671196 0.249957114458 +0.949743270874 0.313029706478 +0.923439562321 0.383743852377 +0.887845396996 0.460141569376 +0.84205520153 0.539391338825 +0.786133110523 0.618057072163 +0.721356093884 0.692564308643 +0.650200843811 0.75976228714 +0.576043605804 0.817418932915 +0.50264531374 0.864492714405 +0.433580338955 0.901114821434 +0.37178248167 0.928319692612 +0.319311022758 0.947649896145 +0.277351588011 0.960768282413 +0.246392846107 0.969170033932 +0.226483732462 0.974014937878 +0.217491298914 0.976062119007 +0.219294831157 0.975658476353 +0.231883689761 0.9727435112 +0.255343019962 0.966850459576 +0.289732515812 0.957107663155 +0.334875375032 0.942262351513 +0.390099585056 0.920772612095 +0.453998446465 0.891002416611 +0.524295091629 0.85153657198 +0.597898721695 0.80157148838 +0.67119371891 0.741281926632 +0.740526080132 0.672027647495 +0.802763938904 0.596296846867 +0.855761229992 0.517370939255 +0.898582041264 0.438805609941 +0.931442677975 0.363888144493 +0.955428779125 0.295221209526 +0.972113490105 0.234510570765 +0.983195364475 0.182556256652 +0.99023771286 0.139387428761 +0.99452829361 0.104467004538 +0.997038424015 0.076904065907 +0.998450875282 0.0556378364563 +0.99921643734 0.0395758785307 +0.999624788761 0.0273887142539 +0.999994754791 0.00323925400153 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999821186 0.000586129724979 +0.999994158745 0.00340667366982 +0.999734938145 0.0230207499117 +0.999346017838 0.0361576490104 +0.998676717281 0.0514233447611 +0.997392058372 0.0721729770303 +0.995067596436 0.0991974920034 +0.990993022919 0.133912488818 +0.984134018421 0.177424892783 +0.973069429398 0.230511233211 +0.956001281738 0.293361723423 +0.930886149406 0.365309298038 +0.895721375942 0.444615453482 +0.848986506462 0.528414428234 +0.79015225172 0.612910628319 +0.720102310181 0.693867683411 +0.641279876232 0.767306983471 +0.557440519333 0.830216765404 +0.473051518202 0.88103479147 +0.392521291971 0.919742882252 +0.319517701864 0.947580218315 +0.256561756134 0.966527700424 +0.204960569739 0.978770136833 +0.165008455515 0.986292004585 +0.136337712407 0.990662395954 +0.118294641376 0.992978513241 +0.110261209309 0.993902444839 +0.111876934767 0.99372202158 +0.123145088553 0.992388606071 +0.14442011714 0.98951613903 +0.176274999976 0.984340906143 +0.219262242317 0.975665867329 +0.27358597517 0.961847484112 +0.338736236095 0.940881371498 +0.413175940514 0.91065120697 +0.494190752506 0.869353353977 +0.578020870686 0.81602191925 +0.660310328007 0.750992774963 +0.736797213554 0.676113426685 +0.804040372372 0.59457463026 +0.859946131706 0.510384857655 +0.903934597969 0.42767059803 +0.936741232872 0.350022494793 +0.959980070591 0.280067294836 +0.975652575493 0.219321534038 +0.985739469528 0.168277546763 +0.991949975491 0.126628652215 +0.995615899563 0.0935347601771 +0.997694373131 0.0678669288754 +0.998828113079 0.048398848623 +0.999437689781 0.0335266962647 +0.999987363815 0.00501690385863 +0.999999821186 0.000534426246304 +0.999999940395 0.000372448586859 +1.0 0.000119029129564 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999701977 0.000800011272077 +0.999990463257 0.0043711415492 +0.999641656876 0.0267680175602 +0.999101102352 0.0423874184489 +0.998184561729 0.0602293685079 +0.996423125267 0.0845032781363 +0.993231594563 0.116150207818 +0.987682342529 0.156470909715 +0.978399455547 0.206722915173 +0.963545680046 0.267543375492 +0.940873742104 0.338757067919 +0.907959580421 0.419057428837 +0.862646818161 0.505806446075 +0.803656816483 0.595092773438 +0.731207489967 0.682155132294 +0.647395074368 0.762154579163 +0.556115865707 0.831104695797 +0.462465047836 0.886637449265 +0.371786564589 0.928318142891 +0.288709551096 0.957416594028 +0.216483563185 0.976286113262 +0.156763002276 0.987636208534 +0.109790302813 0.993954658508 +0.0748182013631 0.997197151184 +0.0505987107754 0.998719036579 +0.0358236134052 0.999357938766 +0.0294548757374 0.999566018581 +0.0309338588268 0.999521255493 +0.0402749329805 0.999188661575 +0.0580519512296 0.998313426971 +0.0852789282799 0.996356964111 +0.123182594776 0.992384016514 +0.172861114144 0.984946131706 +0.234852805734 0.972030937672 +0.308674842119 0.951167464256 +0.392453700304 0.919771492481 +0.482805907726 0.875727295876 +0.57511138916 0.818075120449 +0.664197683334 0.747556686401 +0.745273828506 0.666758537292 +0.814802885056 0.579738020897 +0.871015846729 0.491254806519 +0.913925111294 0.405882418156 +0.944920241833 0.32730025053 +0.9661642313 0.257927387953 +0.980019807816 0.198899120092 +0.988643705845 0.15027834475 +0.993779122829 0.111368469894 +0.996711969376 0.0810259431601 +0.99832123518 0.0579158477485 +0.999194145203 0.0401336625218 +0.999975264072 0.00703474925831 +0.999999403954 0.00107272050809 +0.999999642372 0.00074806943303 +0.999999940395 0.000315559707815 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999403954 0.00107501121238 +0.999984741211 0.0055289962329 +0.999527394772 0.030738580972 +0.998786389828 0.0492509417236 +0.997552990913 0.0699131190777 +0.995180785656 0.0980571433902 +0.990874409676 0.134787544608 +0.983457446098 0.181139394641 +0.971138179302 0.238517329097 +0.951612532139 0.307300180197 +0.92217540741 0.386771589518 +0.880108952522 0.474771618843 +0.823327183723 0.567567050457 +0.751164972782 0.660114347935 +0.665040671825 0.746807157993 +0.568658649921 0.822573423386 +0.467540502548 0.883971571922 +0.3679677248 0.929838478565 +0.275715261698 0.961239218712 +0.195039972663 0.980795025826 +0.128221988678 0.991745352745 +0.0756663680077 0.997132956982 +0.0363807603717 0.999337852001 +0.0085816020146 0.999962985516 +-0.00974187534302 0.999952375889 +-0.0203985199332 0.999791681767 +-0.0247129276395 0.999694466591 +-0.0233692396432 0.999726712704 +-0.0163519345224 0.999866127968 +-0.0029579680413 0.999995470047 +0.0181159358472 0.999835848808 +0.0485994517803 0.998818218708 +0.0903575792909 0.995909333229 +0.144969314337 0.989436149597 +0.213194996119 0.977009475231 +0.294419884682 0.955675959587 +0.386242210865 0.922397255898 +0.484426558018 0.874831855297 +0.583383023739 0.812197089195 +0.677142977715 0.735851287842 +0.760542333126 0.6492882967 +0.83018642664 0.557485640049 +0.884857535362 0.465861558914 +0.925296366215 0.379244416952 +0.95356631279 0.301182836294 +0.972306907177 0.233707398176 +0.984127044678 0.177464112639 +0.991243064404 0.132049262524 +0.995343089104 0.0963928848505 +0.997609972954 0.0690934285522 +0.998851299286 0.0479168742895 +0.999950945377 0.00987852271646 +0.999998271465 0.00187184358947 +0.99999910593 0.00130604498554 +0.999999701977 0.000614349148236 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999998986721 0.00142214330845 +0.999976158142 0.00689455028623 +0.999391853809 0.0348705686629 +0.998406529427 0.0564279220998 +0.996793806553 0.0800121352077 +0.993686676025 0.112189285457 +0.988028466702 0.154271140695 +0.978390693665 0.206764250994 +0.962509155273 0.271249294281 +0.93759816885 0.347719907761 +0.900548934937 0.434754401445 +0.84851205349 0.529175817966 +0.779769778252 0.626065969467 +0.694665372372 0.719332873821 +0.59619051218 0.802842855453 +0.489841610193 0.871811330318 +0.382630854845 0.923901259899 +0.281576663256 0.959538638592 +0.192267984152 0.981342256069 +0.118016816676 0.993011474609 +0.0597599744797 0.998212575912 +0.0165321175009 0.999863088131 +-0.0138089861721 0.99990439415 +-0.0338677689433 0.999426186085 +-0.0461578443646 0.998933911324 +-0.05274355039 0.998607933521 +-0.0550513342023 0.998483419418 +-0.053794503212 0.99855196476 +-0.0489589571953 0.998800337315 +-0.0398180782795 0.999206781387 +-0.0249742548913 0.99968791008 +-0.00245544407517 0.999996960163 +0.0300881769508 0.999546945095 +0.0750389248133 0.997180581093 +0.134294658899 0.990941286087 +0.208618760109 0.977996647358 +0.296987384558 0.954881310463 +0.396178305149 0.918173551559 +0.500877022743 0.865518450737 +0.604465007782 0.796631455421 +0.700335621834 0.71381342411 +0.783289432526 0.621656954288 +0.85046172142 0.526036858559 +0.901482999325 0.43281391263 +0.937953650951 0.346760511398 +0.962579190731 0.270999342203 +0.97834777832 0.206966906786 +0.987958431244 0.154719293118 +0.993552148342 0.113373033702 +0.996671140194 0.0815252363682 +0.998396992683 0.0565961077809 +0.999909460545 0.0134380655363 +0.999995231628 0.00306318607181 +0.999997735023 0.00213813106529 +0.999999403954 0.00107172841672 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.000171616848093 +0.999997794628 0.00210204394534 +0.999960899353 0.0088330861181 +0.999216139317 0.0395862683654 +0.99791097641 0.0646025538445 +0.995810270309 0.0914431288838 +0.991738975048 0.12827077508 +0.984367311001 0.176126778126 +0.971946358681 0.235201776028 +0.951685488224 0.307074308395 +0.920319080353 0.391167879105 +0.874440431595 0.485132902861 +0.811333715916 0.584582924843 +0.7300735116 0.683368563652 +0.632498443127 0.774561285973 +0.523535788059 0.852003276348 +0.4105040133 0.911858618259 +0.301524043083 0.953458249569 +0.203672990203 0.979038834572 +0.121629245579 0.992575407028 +0.0572233200073 0.998361229897 +0.00980965327471 0.999951720238 +-0.0229136049747 0.999737203121 +-0.0440153777599 0.999030709267 +-0.0566121600568 0.9983959198 +-0.0634002685547 0.997987806797 +-0.0664259940386 0.997791230679 +-0.0670218393207 0.99775147438 +-0.0658281072974 0.997830867767 +-0.062829002738 0.998024106026 +-0.0573682710528 0.998352944851 +-0.048140194267 0.998840391636 +-0.0331946760416 0.99944871664 +-0.0100137311965 0.999949753284 +0.0242682062089 0.999705374241 +0.0724378973246 0.997372686863 +0.136558383703 0.990631818771 +0.217174917459 0.976132571697 +0.312578350306 0.949891746044 +0.41845408082 0.908237934113 +0.528256952763 0.849084377289 +0.634400188923 0.77300453186 +0.729928314686 0.683523595333 +0.81001496315 0.586408913136 +0.872691512108 0.488271534443 +0.918636143208 0.395104318857 +0.950313210487 0.311294674873 +0.970946550369 0.239296391606 +0.983697831631 0.179826855659 +0.991205275059 0.132332459092 +0.995441198349 0.0953758731484 +0.997799932957 0.0662947297096 +0.999839842319 0.0178920328617 +0.999989032745 0.00466753169894 +0.999994695187 0.00325867487118 +0.999998450279 0.00168956373818 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000247095536906 +0.999996244907 0.00273451977409 +0.999941825867 0.0107872476801 +0.999029994011 0.0440320633352 +0.997361063957 0.0726001933217 +0.99472117424 0.102613523602 +0.989562392235 0.144104003906 +0.980266153812 0.197680979967 +0.964775919914 0.263072133064 +0.939756393433 0.341844320297 +0.901522517204 0.43273204565 +0.846525430679 0.532348096371 +0.772455155849 0.635069012642 +0.679516732693 0.733659863472 +0.571320235729 0.8207269907 +0.454762637615 0.890612661839 +0.338672846556 0.940903961658 +0.231689348817 0.9727897048 +0.140296518803 0.99010938406 +0.0677863135934 0.99769961834 +0.0143257118762 0.999897241592 +-0.0222239065915 0.999752759933 +-0.0452365316451 0.998976171017 +-0.0583722665906 0.998294830322 +-0.0649269893765 0.997889757156 +-0.0675001889467 0.997718930244 +-0.0679149478674 0.997690975666 +-0.0672831684351 0.997733652592 +-0.0661148428917 0.997811973095 +-0.0643964484334 0.997924387455 +-0.0616060122848 0.998100340366 +-0.0566647909582 0.998393058777 +-0.0478601679206 0.99885392189 +-0.0328040719032 0.999461650848 +-0.00850787386298 0.999963700771 +0.0283310357481 0.999598264694 +0.0807772949338 0.996732056141 +0.150840446353 0.988557875156 +0.238530904055 0.971134722233 +0.341090977192 0.940029859543 +0.452834635973 0.891594409943 +0.565935671329 0.824449300766 +0.672099411488 0.740460515022 +0.764514446259 0.644606471062 +0.839250683784 0.543744325638 +0.895587861538 0.444884330034 +0.935347557068 0.353729218245 +0.961748063564 0.273934930563 +0.978322386742 0.207087233663 +0.98820567131 0.153130739927 +0.993845105171 0.110775224864 +0.997021555901 0.0771226212382 +0.99972563982 0.0234183892608 +0.999976694584 0.0068121580407 +0.999988555908 0.00475681666285 +0.999997079372 0.00235159345903 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999940395 0.000350254529621 +0.999993860722 0.00350746745244 +0.9999153018 0.0130050862208 +0.998824000359 0.0484802946448 +0.996731758118 0.0807800516486 +0.993481099606 0.113995537162 +0.987066864967 0.160307794809 +0.975562691689 0.219720259309 +0.956629037857 0.291308522224 +0.926369488239 0.376615434885 +0.880765378475 0.47355183959 +0.816328167915 0.577587962151 +0.731465756893 0.681877911091 +0.62785756588 0.778327941895 +0.511086165905 0.859529137611 +0.389902889729 0.920855760574 +0.274178534746 0.961678504944 +0.17240858078 0.98502522707 +0.0898948013783 0.995951116085 +0.0282211378217 0.999601364136 +-0.0141264405102 0.999900043011 +-0.0405704081059 0.999176561832 +-0.0552319511771 0.998472988605 +-0.0620175302029 0.998074948788 +-0.0641030445695 0.997942984104 +-0.0637735798955 0.997964084148 +-0.0624990314245 0.998044669628 +-0.0611080043018 0.99813079834 +-0.0599575154483 0.998200714588 +-0.0590341761708 0.99825578928 +-0.0579688996077 0.998318195343 +-0.0559648834169 0.998432397842 +-0.0516684390604 0.998664259911 +-0.0430307090282 0.999073565006 +-0.027244951576 0.999628543854 +-0.000864625384565 0.999999463558 +0.0397963225842 0.999207556248 +0.0979283750057 0.995193421841 +0.17520904541 0.98453104496 +0.27073174715 0.962654709816 +0.380314290524 0.924857199192 +0.496700495481 0.867921948433 +0.610916376114 0.791694939137 +0.714422047138 0.699714958668 +0.801152527332 0.598460018635 +0.868559241295 0.49558493495 +0.917370438576 0.39803403616 +0.950477600098 0.310791492462 +0.971627950668 0.236513733864 +0.984420359135 0.175829783082 +0.991810917854 0.127713441849 +0.996023356915 0.0890901908278 +0.999546051025 0.0301190838218 +0.999954104424 0.00958168506622 +0.999977469444 0.00669193547219 +0.999994754791 0.00322307390161 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999880791 0.000488783873152 +0.999990165234 0.00443645566702 +0.999880135059 0.0154814980924 +0.998596429825 0.0529642440379 +0.996018946171 0.089140728116 +0.992087423801 0.125547334552 +0.984264135361 0.176702544093 +0.970284819603 0.241964489222 +0.947595715523 0.319471150637 +0.911743700504 0.410758972168 +0.858498811722 0.512815475464 +0.784655272961 0.619932055473 +0.689633309841 0.724158406258 +0.576831817627 0.816862881184 +0.453837841749 0.891084194183 +0.330943107605 0.94365054369 +0.218478068709 0.975841760635 +0.124182283878 0.992259085178 +0.0517752729356 0.998658537865 +0.00104381237179 0.999999344349 +-0.0310357064009 0.999518036842 +-0.0488534532487 0.998805522919 +-0.056925136596 0.99837833643 +-0.0590942241251 0.998252272606 +-0.0582010895014 0.998304724693 +-0.056105054915 0.998424708843 +-0.0538916476071 0.998546719551 +-0.0521169453859 0.998640656471 +-0.050999134779 0.998698472977 +-0.0505222193897 0.998722493649 +-0.0504485964775 0.998726427555 +-0.0502443760633 0.998736679554 +-0.0489317402244 0.998802065849 +-0.0448959060013 0.99899160862 +-0.0357123054564 0.999362051487 +-0.0181030351669 0.999836146832 +0.0118506867439 0.99992954731 +0.05812786147 0.998309016228 +0.123798675835 0.992307007313 +0.209799423814 0.977744400501 +0.313814818859 0.949484169483 +0.429851412773 0.902899503708 +0.549032270908 0.83580082655 +0.661624193192 0.749835371971 +0.759533882141 0.650467514992 +0.838121652603 0.545483112335 +0.896606385708 0.442828059196 +0.937186360359 0.348827928305 +0.963597655296 0.267355978489 +0.979816019535 0.199899986386 +0.989311218262 0.145818278193 +0.994790256023 0.101940974593 +0.999281644821 0.037888970226 +0.999916374683 0.0129263093695 +0.999959051609 0.00903049018234 +0.999990522861 0.00435004802421 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999761581 0.000671528046951 +0.999984681606 0.00553435180336 +0.999834358692 0.0182015560567 +0.998341083527 0.0575762279332 +0.995188117027 0.0979827940464 +0.990472853184 0.137707859278 +0.980965316296 0.194181799889 +0.96407854557 0.265616416931 +0.937098681927 0.349063843489 +0.895011126995 0.446043550968 +0.833532631397 0.55247014761 +0.750035107136 0.661397576332 +0.645319342613 0.763912677765 +0.524764955044 0.85124707222 +0.397896021605 0.917430400848 +0.276117414236 0.96112382412 +0.16957372427 0.985517203808 +0.0846667662263 0.996408998966 +0.0232293941081 0.999729812145 +-0.0167389810085 0.999859750271 +-0.039534304291 0.999218165874 +-0.0501722209156 0.998740196228 +-0.0532225221395 0.998582482338 +-0.0522057376802 0.998636007309 +-0.0494812950492 0.998774886131 +-0.0464445725083 0.998920679092 +-0.0438211709261 0.999039173126 +-0.0419351309538 0.999120175838 +-0.0408910773695 0.999163448811 +-0.040665384382 0.999172687531 +-0.0411185249686 0.999154090881 +-0.0419327057898 0.999120235443 +-0.0424764752388 0.99909734726 +-0.04159803316 0.999134302139 +-0.0373875871301 0.999300599098 +-0.0269949305803 0.999635279179 +-0.006638425868 0.999977707863 +0.0280374903232 0.999606490135 +0.081154383719 0.996701300144 +0.155372694135 0.987855613232 +0.250497162342 0.968117058277 +0.362449914217 0.932002842426 +0.483317404985 0.875445067883 +0.602888941765 0.797824919224 +0.711298942566 0.702889084816 +0.801578700542 0.597888946533 +0.870923519135 0.491417944431 +0.92033457756 0.391131162643 +0.953206300735 0.302319914103 +0.973757326603 0.227588042617 +0.985978782177 0.166869103909 +0.993126571178 0.117041766644 +0.99885559082 0.0478242188692 +0.999846696854 0.0175043921918 +0.999925076962 0.0122329741716 +0.999983251095 0.0057813427411 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999582767 0.000908292480744 +0.999976813793 0.00680999271572 +0.999776482582 0.0211399979889 +0.998057663441 0.0622954703867 +0.994263589382 0.106956116855 +0.98868727684 0.149990960956 +0.977272331715 0.211987227201 +0.957116544247 0.289702057838 +0.925453960896 0.378859460354 +0.87671661377 0.481006354094 +0.806739866734 0.590906262398 +0.713738143444 0.700412273407 +0.600155889988 0.799882650375 +0.473450124264 0.880820393562 +0.344871520996 0.938649654388 +0.226432919502 0.974026679993 +0.127520084381 0.991835832596 +0.0528156720102 0.998604059219 +0.00218783179298 0.999997317791 +-0.0279735252261 0.999608457088 +-0.0429226160049 0.999078214169 +-0.0479623675346 0.998848974705 +-0.0474455170333 0.998873651028 +-0.0444160848856 0.999013066292 +-0.0407161004841 0.999170660973 +-0.0373112671077 0.99930369854 +-0.034629393369 0.999399900436 +-0.0328151807189 0.999461352825 +-0.031884662807 0.999491274357 +-0.0318005271256 0.999494016171 +-0.0324837341905 0.999472200871 +-0.0337688177824 0.999429583549 +-0.0352909564972 0.999377012253 +-0.0362982489169 0.999340832233 +-0.0353928133845 0.999373197556 +-0.0302640758455 0.9995418787 +-0.0175270438194 0.999846279621 +0.00715440977365 0.999974370003 +0.0484922789037 0.998823463917 +0.110479563475 0.993878304958 +0.194896131754 0.98082369566 +0.299847334623 0.953987121582 +0.419064640999 0.907956242561 +0.542707204819 0.839921712875 +0.659761309624 0.751474916935 +0.761077404022 0.648660778999 +0.841556668282 0.540168523788 +0.900556147099 0.43473932147 +0.94074511528 0.339113980532 +0.966362059116 0.257183849812 +0.981857717037 0.189618676901 +0.991047084332 0.1335105896 +0.998239159584 0.0593148209155 +0.99973076582 0.0232036020607 +0.999868273735 0.0162234343588 +0.999971270561 0.00756606413051 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999284744 0.00120948627591 +0.999965786934 0.00826680660248 +0.999705612659 0.0242633745074 +0.997748553753 0.0670648962259 +0.993242502213 0.11605732888 +0.986726522446 0.162390261889 +0.973178744316 0.230048984289 +0.949380934238 0.314125955105 +0.912665903568 0.408705621958 +0.856931865215 0.515429139137 +0.778327286243 0.627858400345 +0.676176786423 0.73673915863 +0.55478322506 0.831994891167 +0.423662722111 0.905819475651 +0.29545250535 0.955357313156 +0.182223677635 0.983256816864 +0.0921115130186 0.995748400688 +0.0278517659754 0.999611616135 +-0.0125859808177 0.99992030859 +-0.0341586582363 0.999416232109 +-0.0427432321012 0.999085903168 +-0.0436288192868 0.999047517776 +-0.040756482631 0.999168872833 +-0.0366228371859 0.999328970909 +-0.0325750894845 0.99946898222 +-0.0292138531804 0.999572992325 +-0.0267307348549 0.999642550945 +-0.0251303724945 0.999683976173 +-0.0243570525199 0.999703228474 +-0.0243558231741 0.999703288078 +-0.0250865444541 0.999684989452 +-0.0264914035797 0.999648869038 +-0.0284066367894 0.999596357346 +-0.0304007623345 0.999537706375 +-0.0315306931734 0.99950248003 +-0.0300389751792 0.999548614025 +-0.0230769757181 0.999733567238 +-0.00661940639839 0.999977767467 +0.0242234170437 0.99970638752 +0.0743325352669 0.997233510017 +0.147147983313 0.989114284515 +0.242960214615 0.970035910606 +0.357586055994 0.933879852295 +0.482326388359 0.875991404057 +0.605784535408 0.795628428459 +0.717023253441 0.697049081326 +0.808558285236 0.58841586113 +0.877718031406 0.479177385569 +0.926029682159 0.377450436354 +0.957468032837 0.288538128138 +0.976833701134 0.213999077678 +0.988481879234 0.151337847114 +0.997375667095 0.0723970830441 +0.999549686909 0.0299981478602 +0.999779641628 0.0209866277874 +0.999952435493 0.00975018553436 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999998748302 0.00158558867406 +0.999950945377 0.00990157667547 +0.999617576599 0.0276513248682 +0.997408747673 0.0719420090318 +0.992125868797 0.125243425369 +0.984608709812 0.174772307277 +0.968664884567 0.248371243477 +0.940838158131 0.338855922222 +0.898709475994 0.438543349504 +0.835671305656 0.549229860306 +0.748397827148 0.663249790668 +0.637583017349 0.770381391048 +0.509546458721 0.860442996025 +0.375750929117 0.926720440388 +0.249802589417 0.968296587467 +0.143293261528 0.989680051804 +0.0627123787999 0.998031318188 +0.00874256901443 0.999961733818 +-0.0223909318447 0.999749064445 +-0.0366919003427 0.999326467514 +-0.0403341017663 0.99918615818 +-0.0383402109146 0.999264419079 +-0.0341110303998 0.99941778183 +-0.029583029449 0.999562084675 +-0.0256613790989 0.999670386314 +-0.0226486846805 0.999743282795 +-0.0205515660346 0.999788582325 +-0.0192658081651 0.999814033508 +-0.0186774265021 0.9998254776 +-0.0187143180519 0.99982458353 +-0.0193626116961 0.999812364578 +-0.0206439569592 0.999786496162 +-0.0225486252457 0.999745547771 +-0.0249016154557 0.999689817429 +-0.0271498654038 0.999631285667 +-0.0280649140477 0.999605894089 +-0.0254056733102 0.99967700243 +-0.0156691111624 0.999876976013 +0.00586287071928 0.999982714653 +0.0445439331234 0.999007225037 +0.105124905705 0.994458913803 +0.18998080492 0.981787741184 +0.297316014767 0.954778969288 +0.420267343521 0.907400131226 +0.547853589058 0.836573958397 +0.667868971825 0.744278669357 +0.770471870899 0.637473642826 +0.850590646267 0.525827944279 +0.908128798008 0.418690085411 +0.946435630322 0.322891771793 +0.970508635044 0.241066172719 +0.985202312469 0.171393737197 +0.996140897274 0.0877670645714 +0.999259293079 0.0384736247361 +0.999636948109 0.0269361417741 +0.999923408031 0.0123723801225 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999997913837 0.00204641814344 +0.999931514263 0.0117033403367 +0.99950838089 0.0313518419862 +0.997026085854 0.0770636498928 +0.990887463093 0.134690195322 +0.982285439968 0.187390446663 +0.963680624962 0.267056703568 +0.931451499462 0.363864779472 +0.883682727814 0.468086093664 +0.813292860985 0.581854403019 +0.717689037323 0.696363210678 +0.599108636379 0.800667583942 +0.465880721807 0.884847402573 +0.331154584885 0.943576335907 +0.209066808224 0.977901101112 +0.110253475606 0.993903279305 +0.0393175184727 0.999226748943 +-0.00505762454122 0.999986886978 +-0.0281311478466 0.999603867531 +-0.0366173498333 0.999329209328 +-0.0366895310581 0.999326527119 +-0.032921679318 0.999457657337 +-0.0281244870275 0.999604105949 +-0.0237165279686 0.999718368053 +-0.0202354751527 0.999794900417 +-0.0177533086389 0.99984228611 +-0.0161400176585 0.999869406223 +-0.0152113260701 0.999884009361 +-0.0148112811148 0.999890208244 +-0.0148544814438 0.99988925457 +-0.0153422588482 0.999882161617 +-0.0163510572165 0.999866068363 +-0.0179797597229 0.999838113785 +-0.0202442314476 0.999794960022 +-0.0228979643434 0.999737560749 +-0.0251650139689 0.999683201313 +-0.0253941658884 0.999677538872 +-0.0207096524537 0.999785423279 +-0.00683636870235 0.999976336956 +0.0216357018799 0.999765694141 +0.070309124887 0.997525155544 +0.143314018846 0.989676952362 +0.241252616048 0.970462024212 +0.359575986862 0.93311560154 +0.488537430763 0.872542798519 +0.615421950817 0.788197398186 +0.728348433971 0.685206651688 +0.819663643837 0.572844445705 +0.887206077576 0.461373001337 +0.933279395103 0.359150260687 +0.962854683399 0.27001991868 +0.981175243855 0.193118616939 +0.994486033916 0.104868650436 +0.998832046986 0.0483140647411 +0.999426543713 0.0338562913239 +0.999880373478 0.0154592460021 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999995946884 0.00282518495806 +0.999902307987 0.0139750167727 +0.999359130859 0.0357918590307 +0.996547162533 0.0830277502537 +0.989411175251 0.145138517022 +0.979542791843 0.20123501122 +0.957736551762 0.287646055222 +0.920359253883 0.391073077917 +0.86622107029 0.499660551548 +0.787857830524 0.615857064724 +0.683755934238 0.729710459709 +0.558045566082 0.829810142517 +0.421176284552 0.906978785992 +0.287626177073 0.957742512226 +0.171350121498 0.985209882259 +0.0814752653241 0.9966750741 +0.0204836409539 0.999790072441 +-0.0148414559662 0.999889135361 +-0.0309217832983 0.999521493912 +-0.0348288193345 0.999393105507 +-0.0324563197792 0.999472796917 +-0.0277784671634 0.999613940716 +-0.0229912567884 0.999735355377 +-0.0190453529358 0.999818205833 +-0.0161809790879 0.999868929386 +-0.0143004432321 0.999897360802 +-0.0131826577708 0.9999127388 +-0.0125979771838 0.999920427799 +-0.0123687563464 0.999923288822 +-0.0124035272747 0.99992287159 +-0.0127115743235 0.999918937683 +-0.0133983045816 0.999909937382 +-0.0146305356175 0.999892532825 +-0.0165550373495 0.999862611294 +-0.0191546007991 0.99981623888 +-0.0220213700086 0.999756991863 +-0.0240393616259 0.999710857868 +-0.0229994356632 0.999735116959 +-0.0152665851638 0.999883234501 +0.00425801659003 0.999990522861 +0.0415623635054 0.99913585186 +0.102125786245 0.994771242142 +0.188818246126 0.982011735439 +0.299734383821 0.954022526741 +0.427134752274 0.904187738895 +0.558674812317 0.829386591911 +0.680952310562 0.732327759266 +0.783679008484 0.621165633202 +0.862172961235 0.506613731384 +0.917221963406 0.398375183344 +0.953347146511 0.301875561476 +0.976077020168 0.217423498631 +0.992236435413 0.124364070594 +0.998192071915 0.0601022876799 +0.999110639095 0.0421634279191 +0.999818980694 0.0190202780068 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999993622303 0.00357580510899 +0.999868988991 0.0161840301007 +0.999190568924 0.0402272976935 +0.996062517166 0.0886530354619 +0.987887680531 0.155170068145 +0.976722121239 0.214507818222 +0.951473891735 0.307728290558 +0.908615112305 0.417633503675 +0.8479347229 0.530099987984 +0.761624932289 0.648017466068 +0.649453639984 0.76040071249 +0.517561018467 0.855646073818 +0.37839820981 0.925642609596 +0.24742397666 0.968907117844 +0.13800214231 0.99043148756 +0.0574340745807 0.998349130154 +0.00602353038266 0.999981760979 +-0.0211745183915 0.999775707722 +-0.031471349299 0.999504387379 +-0.0319727659225 0.999488592148 +-0.0280658546835 0.999605834484 +-0.023056814447 0.999733865261 +-0.0185713358223 0.999827444553 +-0.0151759311557 0.999884545803 +-0.0128937968984 0.999916613102 +-0.0115196602419 0.999933183193 +-0.0107874590904 0.99994134903 +-0.0104555469006 0.999945044518 +-0.010347022675 0.999946177006 +-0.0103728435934 0.999945878983 +-0.0105415647849 0.999944210052 +-0.0109639661387 0.999939620495 +-0.0118324318901 0.999929726124 +-0.0133647359908 0.999910414219 +-0.0156928766519 0.999876558781 +-0.0186778400093 0.999825119972 +-0.0216370895505 0.999765515327 +-0.0229760203511 0.999735534191 +-0.0197744797915 0.999804079533 +-0.00751177687198 0.999971628189 +0.0197366978973 0.999805092812 +0.0682810693979 0.997665703297 +0.142876341939 0.989740490913 +0.24425624311 0.969710588455 +0.367210775614 0.930137753487 +0.500648438931 0.865650594234 +0.630434155464 0.776242554188 +0.743927001953 0.668260812759 +0.833679974079 0.552247524261 +0.898468375206 0.439037740231 +0.942038297653 0.335504829884 +0.969895243645 0.243521571159 +0.989334344864 0.145660072565 +0.997307896614 0.0733261182904 +0.998672604561 0.0515066497028 +0.999734282494 0.0230430494994 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99998998642 0.00446266308427 +0.999828338623 0.0185264069587 +0.998989760876 0.0449355840683 +0.995548963547 0.0942457094789 +0.98632478714 0.164812400937 +0.973857700825 0.227158263326 +0.94488799572 0.327393084764 +0.896272599697 0.443502545357 +0.828997015953 0.559252977371 +0.734952747822 0.678117930889 +0.61535358429 0.788250863552 +0.478377044201 0.878153979778 +0.338249981403 0.941056013107 +0.210983663797 0.97748953104 +0.108953811228 0.994046568871 +0.0374801456928 0.99929702282 +-0.00519156176597 0.999986350536 +-0.0254426840693 0.99967610836 +-0.0311456676573 0.999514877796 +-0.0292096938938 0.999573290348 +-0.0244150962681 0.999701678753 +-0.0194164589047 0.999811291695 +-0.0153443757445 0.999881803989 +-0.0124675966799 0.99992197752 +-0.0106590781361 0.999942719936 +-0.00965385418385 0.999953150749 +-0.00917700584978 0.999957740307 +-0.00899967364967 0.999958992004 +-0.00896227173507 0.999959409237 +-0.00898391194642 0.999959290028 +-0.00907061435282 0.999958395958 +-0.00932155735791 0.999956250191 +-0.00992495566607 0.999950408936 +-0.0111232921481 0.999937832355 +-0.0131309442222 0.99991351366 +-0.0159871969372 0.999872088432 +-0.0193315204233 0.999812960625 +-0.0220828615129 0.999756038189 +-0.0220187678933 0.999757349491 +-0.0153529560193 0.999881744385 +0.00340528786182 0.999993979931 +0.0408766902983 0.999164044857 +0.103204362094 0.994660139084 +0.193544641137 0.981091082096 +0.309501677752 0.950898706913 +0.442018121481 0.897005856037 +0.57712829113 0.816653311253 +0.700359225273 0.713790178299 +0.801434755325 0.598082065582 +0.876685261726 0.481063902378 +0.92863124609 0.371003657579 +0.962405800819 0.27161476016 +0.985626399517 0.168937370181 +0.996077120304 0.0884881094098 +0.998060464859 0.0622514896095 +0.999622046947 0.0274891667068 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999984920025 0.00549271702766 +0.999779999256 0.0209713410586 +0.998757898808 0.0498251058161 +0.995012223721 0.0997525304556 +0.984725534916 0.174113482237 +0.970953345299 0.239268749952 +0.938058435917 0.346476197243 +0.883507311344 0.468416631222 +0.809722542763 0.586812496185 +0.708348631859 0.705862224102 +0.582168757915 0.813067615032 +0.441344827414 0.897337079048 +0.301572918892 0.953442811966 +0.17897555232 0.983853340149 +0.0846095532179 0.996413826942 +0.0217605009675 0.999762892723 +-0.0131851462647 0.999912858009 +-0.0277216807008 0.999615311623 +-0.0299643315375 0.999550879002 +-0.0264226943254 0.999650299549 +-0.0212224982679 0.99977439642 +-0.0164248179644 0.99986487627 +-0.0127636585385 0.999918103218 +-0.0102959554642 0.999946475029 +-0.00880552176386 0.999960899353 +-0.00800911337137 0.999967694283 +-0.00764871854335 0.999970495701 +-0.00752593809739 0.999971449375 +-0.00750905508175 0.99997150898 +-0.00753191206604 0.999971330166 +-0.00759697053581 0.999970495701 +-0.00778362154961 0.999969363213 +-0.00825533550233 0.99996560812 +-0.00924505572766 0.999956727028 +-0.0109979100525 0.999939084053 +-0.013657133095 0.999906539917 +-0.0170813724399 0.999853670597 +-0.0205807127059 0.999787628651 +-0.022535296157 0.999745726585 +-0.0199159663171 0.99980121851 +-0.00789738353342 0.999968647957 +0.0200018007308 0.999799787998 +0.0707599893212 0.997492969036 +0.149521142244 0.988758265972 +0.256659269333 0.966501772404 +0.385652393103 0.922643899918 +0.523570716381 0.851982116699 +0.654851436615 0.755757153034 +0.766621530056 0.642098963261 +0.852527678013 0.522681355476 +0.913446426392 0.406958281994 +0.953735053539 0.30064740777 +0.981127440929 0.193361654878 +0.994480729103 0.104919396341 +0.997262716293 0.0739378035069 +0.999478518963 0.0322915539145 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999977767467 0.0066686719656 +0.999724209309 0.0234834048897 +0.998507797718 0.0546072460711 +0.994490146637 0.104828879237 +0.983176648617 0.182656541467 +0.968133449554 0.250434547663 +0.931055963039 0.364875435829 +0.870387136936 0.492367506027 +0.790141403675 0.612923800945 +0.6817958951 0.731542170048 +0.549827337265 0.835278153419 +0.406267762184 0.913753688335 +0.267960757017 0.963429629803 +0.150746554136 0.988572061062 +0.064120747149 0.997941911221 +0.00934983789921 0.999956071377 +-0.0188165064901 0.999822735786 +-0.0286833699793 0.999588131905 +-0.0283477306366 0.999597728252 +-0.023784013465 0.999716699123 +-0.0184615273029 0.999829232693 +-0.0139266410843 0.999902784824 +-0.0106075573713 0.999943315983 +-0.00841948762536 0.999964058399 +-0.0071022324264 0.999974429607 +-0.00638068607077 0.999979376793 +-0.00602898746729 0.999981403351 +-0.00588629487902 0.999982178211 +-0.00585235888138 0.999982655048 +-0.00587848527357 0.999982297421 +-0.00596503214911 0.999981999397 +-0.00617074873298 0.99998062849 +-0.00662638945505 0.999977886677 +-0.00753468694165 0.999971032143 +-0.00913660880178 0.999957740307 +-0.0116241546348 0.999931871891 +-0.0149945355952 0.999887108803 +-0.0188377611339 0.999821960926 +-0.0220202729106 0.999757349491 +-0.02222456038 0.999752819538 +-0.015417589806 0.999880850315 +0.00438766973093 0.99998998642 +0.0444862619042 0.999009728432 +0.111520141363 0.993762016296 +0.20843552053 0.978035867214 +0.331562787294 0.943432927132 +0.46978366375 0.882781207561 +0.607269346714 0.794495820999 +0.728941261768 0.684576034546 +0.825632154942 0.564208328724 +0.896151959896 0.443747073412 +0.943623840809 0.331018835306 +0.975669264793 0.219245374203 +0.992416203022 0.122920170426 +0.99622631073 0.0867924690247 +0.999301970005 0.0373536422849 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999968111515 0.0079880785197 +0.999659478664 0.0260942168534 +0.998244762421 0.0592228472233 +0.994000613689 0.109373241663 +0.981716215611 0.190349698067 +0.965504467487 0.26038557291 +0.924164056778 0.381994754076 +0.857449293137 0.514567792416 +0.771008789539 0.636824131012 +0.65614849329 0.754631280899 +0.519044101238 0.854747354984 +0.373568922281 0.927602171898 +0.2374817729 0.971391737461 +0.126049786806 0.992023527622 +0.0470460914075 0.998892486095 +-0.000247306306846 0.999999821186 +-0.0225196089596 0.999745965004 +-0.0286098178476 0.999590337276 +-0.0263898484409 0.999651432037 +-0.0212216190994 0.999774336815 +-0.0159539468586 0.999872386456 +-0.0117019610479 0.999931335449 +-0.00866532605141 0.999962210655 +-0.00666885776445 0.999977529049 +-0.00543784163892 0.99998497963 +-0.00471980962902 0.999988734722 +-0.0043247109279 0.999990105629 +-0.00412899069488 0.999991357327 +-0.00406145118177 0.999991297722 +-0.00408942904323 0.999991297722 +-0.00421360041946 0.999990820885 +-0.00447550881654 0.999989509583 +-0.00497451517731 0.999987363815 +-0.00587917258963 0.99998241663 +-0.00740928109735 0.99997228384 +-0.00977030117065 0.999951779842 +-0.0130356717855 0.999914646149 +-0.0169788040221 0.999855458736 +-0.0208265446126 0.999783039093 +-0.02286057733 0.999738156796 +-0.0198448132724 0.999802947044 +-0.00650958670303 0.999978482723 +0.0243126042187 0.999704182148 +0.0802117437124 0.99677759409 +0.166302397847 0.98607468605 +0.281783759594 0.959477841854 +0.417906939983 0.908489704132 +0.559417665005 0.828885614872 +0.689655840397 0.724137067795 +0.796748995781 0.60431009531 +0.877127587795 0.480256646872 +0.93222618103 0.361875116825 +0.969291985035 0.245911091566 +0.989870250225 0.141974136233 +0.994940757751 0.100462503731 +0.999094307423 0.0425508320332 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999955415726 0.00944267120212 +0.999581575394 0.0289243515581 +0.997961461544 0.063818924129 +0.993519544601 0.113660797477 +0.980287730694 0.197573915124 +0.962972223759 0.269600629807 +0.917297959328 0.398201018572 +0.844719648361 0.535208463669 +0.75256305933 0.658519566059 +0.631999611855 0.774968385696 +0.490836203098 0.871251583099 +0.344477236271 0.938794434071 +0.21122944355 0.977436304092 +0.105559289455 0.994412899017 +0.0335536263883 0.999436557293 +-0.00722724664956 0.999973773956 +-0.0245996974409 0.999697268009 +-0.0277428347617 0.999614775181 +-0.024200649932 0.999706804752 +-0.0187250375748 0.999824523926 +-0.0136176515371 0.999906778336 +-0.0096466364339 0.999953210354 +-0.00684662070125 0.999976158142 +-0.0049891481176 0.999987006187 +-0.00380288809538 0.99999243021 +-0.00306310108863 0.99999499321 +-0.00261416519061 0.999996185303 +-0.00236325198784 0.99999666214 +-0.00226267054677 0.999996960163 +-0.00229270756245 0.999997079372 +-0.00245423894376 0.999996602535 +-0.00277591007762 0.999995589256 +-0.00333176972345 0.999993979931 +-0.00425858981907 0.999990344048 +-0.00575043866411 0.99998319149 +-0.0080105913803 0.999967575073 +-0.0111544318497 0.999937474728 +-0.0150719014928 0.999885976315 +-0.0192402247339 0.999814391136 +-0.0224062595516 0.999748587608 +-0.0220442339778 0.999756753445 +-0.0136800482869 0.999906122684 +0.00939654000103 0.999955534935 +0.0552226603031 0.998473823071 +0.130588814616 0.991436183453 +0.237349793315 0.971424043179 +0.369412779808 0.929265081882 +0.512811422348 0.858500957489 +0.650000929832 0.759932994843 +0.766722142696 0.641978979111 +0.85686403513 0.515541851521 +0.91978341341 0.392425745726 +0.962076246738 0.272780269384 +0.986866533756 0.161535724998 +0.993415057659 0.114568352699 +0.998860061169 0.0477344691753 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999939322472 0.0110179334879 +0.999489247799 0.0319577045739 +0.997661054134 0.0683548748493 +0.993046402931 0.117723219097 +0.978859901428 0.204531088471 +0.960459172726 0.278419852257 +0.91022002697 0.414124548435 +0.831800758839 0.555073440075 +0.734121441841 0.679017961025 +0.60833132267 0.793682992458 +0.463880211115 0.8858974576 +0.317538797855 0.948244869709 +0.187861844897 0.982195258141 +0.0882576555014 0.996097385883 +0.0230556149036 0.999733924866 +-0.0117939505726 0.999930262566 +-0.0250123292208 0.999686658382 +-0.0258602276444 0.99966520071 +-0.0214141216129 0.999770224094 +-0.0158148296177 0.999874651432 +-0.0108878202736 0.99994045496 +-0.00713630113751 0.99997407198 +-0.00448547489941 0.999989688396 +-0.0026841245126 0.999995946884 +-0.00147818145342 0.999998390675 +-0.000673922651913 0.999999165535 +-0.000147169048432 0.999999761581 +0.000169479550095 0.999999642372 +0.000306489557261 0.999999463558 +0.000274875405012 0.999999582767 +7.26264988771e-05 0.999999403954 +-0.000319422717439 0.999999523163 +-0.000956070551183 0.99999910593 +-0.00194599980023 0.999997854233 +-0.00345634738915 0.999993562698 +-0.00567760271952 0.999983489513 +-0.00874284189194 0.999961197376 +-0.0126137770712 0.999920010567 +-0.0169377084821 0.999856054783 +-0.0208123214543 0.999783098698 +-0.0223220381886 0.999750554562 +-0.0178025830537 0.999841034412 +-0.00121445709374 0.999998867512 +0.0355170667171 0.999368667603 +0.100404605269 0.994946181774 +0.197692409158 0.980263888836 +0.324071317911 0.946032464504 +0.467407554388 0.884041786194 +0.609961152077 0.792431235313 +0.735489368439 0.677535951138 +0.835248887539 0.549871861935 +0.906175196171 0.422901988029 +0.95393872261 0.300000995398 +0.983350872993 0.181714996696 +0.991630673409 0.129103332758 +0.998608291149 0.0527381971478 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999916553497 0.0129155525938 +0.999370396137 0.0354793332517 +0.997316658497 0.0732088088989 +0.992514133453 0.12212972343 +0.977329194546 0.211724877357 +0.957793772221 0.287455826998 +0.90274900198 0.430166780949 +0.818538486958 0.574451267719 +0.715547442436 0.698563873768 +0.585036039352 0.811007022858 +0.438065677881 0.898942768574 +0.29256182909 0.956246256828 +0.167027056217 0.985952138901 +0.0736061036587 0.997287154198 +0.0148652326316 0.999889373779 +-0.0146916415542 0.999891757965 +-0.0244588535279 0.999700665474 +-0.0235972180963 0.999721050262 +-0.0186373852193 0.999825775623 +-0.0131261758506 0.999913454056 +-0.00847722310573 0.999963641167 +-0.00498525798321 0.999987363815 +-0.00250450568274 0.999996423721 +-0.000780331320129 0.999999403954 +0.000416371913161 0.999999344349 +0.00161103252321 0.999998271465 +0.0182280894369 0.999833345413 +0.0783025100827 0.996929526329 +0.0447078607976 0.998999655247 +0.00483392411843 0.999988138676 +0.00206873216666 0.999997437 +0.00163777743001 0.999998092651 +0.000957705022302 0.999999165535 +-6.11071372987e-05 0.999999701977 +-0.00156424148008 0.999998509884 +-0.00372770009562 0.999992728233 +-0.00669039553031 0.999977350235 +-0.0104549452662 0.999944806099 +-0.0147770158947 0.99989014864 +-0.018998157233 0.999819099903 +-0.0216783545911 0.999764621258 +-0.0198849700391 0.999801814556 +-0.00834354013205 0.999964535236 +0.0207323729992 0.999784767628 +0.0760991871357 0.997099995613 +0.163962230086 0.986466169357 +0.283682584763 0.958917975426 +0.425304412842 0.905050098896 +0.571518838406 0.820588588715 +0.704679846764 0.709524989128 +0.81341022253 0.581690371037 +0.892093896866 0.45184931159 +0.945276260376 0.326270192862 +0.979484856129 0.201516464353 +0.989646673203 0.143522590399 +0.998349487782 0.0574299097061 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999890983105 0.0147617170587 +0.99924069643 0.0389600768685 +0.996980249882 0.077654927969 +0.992034077644 0.12596873939 +0.97592908144 0.218087509274 +0.955376088619 0.29539167881 +0.895593225956 0.444872975349 +0.806052148342 0.591844141483 +0.698291659355 0.715813100338 +0.56375515461 0.825941324234 +0.414965957403 0.909836292267 +0.270765185356 0.962645113468 +0.14940699935 0.98877543211 +0.0617454126477 0.998091697693 +0.00873190350831 0.99996137619 +-0.0163446683437 0.999866425991 +-0.0233451910317 0.999726951122 +-0.0212175771594 0.999774694443 +-0.0159485843033 0.999872505665 +-0.0105657037348 0.999944090843 +-0.00615428341553 0.999980330467 +-0.0028608457651 0.999995470047 +-0.000498487905134 0.999999403954 +0.00117936776951 0.999998986721 +0.0023773140274 0.999996721745 +0.00771903805435 0.999969542027 +0.185402542353 0.982662141323 +0.397325783968 0.917677044868 +0.359260380268 0.933236777782 +0.0353630743921 0.999373853207 +0.00410240702331 0.999991178513 +0.00364837422967 0.999992907047 +0.00294072926044 0.999995350838 +0.00190151087008 0.999997973442 +0.000401580444304 0.999999463558 +-0.00172104488593 0.999998211861 +-0.00460211699829 0.999988973141 +-0.00826494395733 0.999965369701 +-0.0125290136784 0.999920964241 +-0.0168983396143 0.999856770039 +-0.0202880389988 0.99979364872 +-0.0203857421875 0.999791800976 +-0.0126911802217 0.999919116497 +0.0100754890591 0.99994879961 +0.057010397315 0.998372852802 +0.135842993855 0.990729987621 +0.248353436589 0.968669295311 +0.386914521456 0.922115325928 +0.535167038441 0.844746112823 +0.674615323544 0.738169193268 +0.791509687901 0.611155927181 +0.877593398094 0.47940531373 +0.936153888702 0.351589500904 +0.975288629532 0.220933377743 +0.987481951714 0.157730698586 +0.998094916344 0.061697024852 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99986076355 0.0166847687215 +0.99909299612 0.042581371963 +0.996635377407 0.0819616615772 +0.991559267044 0.12965375185 +0.974557161331 0.224138408899 +0.95302760601 0.302882969379 +0.888431549072 0.459008306265 +0.793919920921 0.608021438122 +0.681782305241 0.731554746628 +0.543777644634 0.839228987694 +0.393773347139 0.919207394123 +0.251319348812 0.967903792858 +0.134240984917 0.990948498249 +0.0520640723407 0.99864345789 +0.00423839082941 0.999990820885 +-0.016975639388 0.99985563755 +-0.021732211113 0.99976336956 +-0.0186755415052 0.999825358391 +-0.0132520580664 0.999911665916 +-0.00803099479526 0.99996727705 +-0.00383335445076 0.999992311001 +-0.000700261327438 0.999999344349 +0.0015754555352 0.999998509884 +0.00322496658191 0.999994456768 +0.00442878063768 0.999989748001 +0.0111949974671 0.999936878681 +0.225930631161 0.974142611027 +0.119933664799 0.992781281471 +0.319071799517 0.947730123997 +0.0467594750226 0.998905539513 +0.00622682552785 0.999980211258 +0.00583831034601 0.999982476234 +0.00507262162864 0.99998664856 +0.00396944209933 0.999991834164 +0.00246896664612 0.999996423721 +0.000376555137336 0.999999821186 +-0.00244091963395 0.999996423721 +-0.00601372122765 0.999981701374 +-0.0101959276944 0.999947488308 +-0.0145935509354 0.999893188477 +-0.0183779429644 0.9998306036 +-0.0197443980724 0.999804317951 +-0.0149264018983 0.9998883605 +0.0027107137721 0.999995708466 +0.0422661527991 0.999105989933 +0.112578108907 0.993642568588 +0.217586800456 0.976040780544 +0.352062612772 0.935976266861 +0.501003324986 0.865445137024 +0.645583868027 0.763689041138 +0.769865274429 0.638206362724 +0.862947225571 0.505293369293 +0.926783800125 0.375594735146 +0.970866858959 0.239618122578 +0.985192000866 0.171454131603 +0.997866868973 0.0652816593647 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999825835228 0.0186582561582 +0.998927295208 0.0463056415319 +0.996285617352 0.0861105173826 +0.991088330746 0.133206054568 +0.97321408987 0.229899257421 +0.950748741627 0.309962153435 +0.88142067194 0.472331762314 +0.782446265221 0.622717559338 +0.666422069073 0.745574057102 +0.525554835796 0.850759327412 +0.374897122383 0.927066206932 +0.234497487545 0.972116529942 +0.121621310711 0.992576241493 +0.0444935075939 0.999009311199 +0.00122256332543 0.999998569489 +-0.0167598631233 0.999858915806 +-0.0197526197881 0.999804615974 +-0.0160427689552 0.999870896339 +-0.0105713736266 0.999943494797 +-0.0055174306035 0.999984502792 +-0.00149820221122 0.999998629093 +0.00151651387569 0.999998509884 +0.00373903289437 0.999992489815 +0.00538166658953 0.999985218048 +0.00660264817998 0.999977469444 +0.00844893604517 0.99996393919 +0.0428734458983 0.999079942703 +0.0367727428675 0.999323427677 +0.0490016788244 0.998798012733 +0.016066852957 0.999869763851 +0.00907493755221 0.999958336353 +0.0116038890556 0.999932289124 +0.00920144561678 0.99995714426 +0.00627752579749 0.999980032444 +0.00465903803706 0.999988853931 +0.00258427276276 0.999996244907 +-0.000188305115444 0.999999403954 +-0.00369233591482 0.999992907047 +-0.00780312437564 0.999969065189 +-0.0121890520677 0.999925494194 +-0.0161938983947 0.999868571758 +-0.018399823457 0.99983048439 +-0.0156733114272 0.999876797199 +-0.00204180716537 0.999997615814 +0.0313946865499 0.999506652355 +0.0942275971174 0.995550394058 +0.192166373134 0.981362164021 +0.322178810835 0.946678459644 +0.470768719912 0.882256507874 +0.619229316711 0.78521001339 +0.749739348888 0.661733090878 +0.849004387856 0.528385162354 +0.917686760426 0.397303909063 +0.966471254826 0.256773233414 +0.982904553413 0.184114262462 +0.997679650784 0.0680821090937 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999786674976 0.0206540804356 +0.998745024204 0.0500835180283 +0.995933711529 0.0900887697935 +0.990619421005 0.136649876833 +0.971899986267 0.235393702984 +0.94853746891 0.316664457321 +0.874528706074 0.484973490238 +0.771611332893 0.636093139648 +0.65214908123 0.75809019804 +0.508946835995 0.860797524452 +0.358091294765 0.933686137199 +0.219952568412 0.975510299206 +0.111141808331 0.99380427599 +0.0386358462274 0.999252974987 +-0.000644574058242 0.999999463558 +-0.0159254129976 0.999872863293 +-0.0175334960222 0.999845921993 +-0.0133702410385 0.999910056591 +-0.00791150983423 0.99996817112 +-0.00300949322991 0.999994754791 +0.000874550954904 0.99999922514 +0.00381584325805 0.999992370605 +0.00602214364335 0.999981641769 +0.00768545176834 0.99996984005 +0.00894330348819 0.999959647655 +0.00997324008495 0.999949872494 +0.0144609231502 0.999894559383 +0.00663501443341 0.999977648258 +0.0123272305354 0.99992364645 +0.0123775908723 0.999922692776 +0.0132642379031 0.999911367893 +0.0302072595805 0.999543309212 +0.0183649193496 0.999830901623 +0.00894308649004 0.999959528446 +0.00699868798256 0.999975144863 +0.00492258463055 0.999987661839 +0.00217571109533 0.999997377396 +-0.00127464835532 0.999998450279 +-0.00531370798126 0.999985039234 +-0.00964801292866 0.999952673912 +-0.0137395057827 0.99990516901 +-0.0164643693715 0.99986410141 +-0.0152253657579 0.999883413315 +-0.00470002461225 0.999988377094 +0.0236653890461 0.999719619751 +0.0799096375704 0.996801495552 +0.171179682016 0.985239446163 +0.296457767487 0.95504540205 +0.443861871958 0.896094977856 +0.595167338848 0.803601562977 +0.730915665627 0.682467281818 +0.835708975792 0.549171566963 +0.908872425556 0.417073488235 +0.962115585804 0.272640913725 +0.980632483959 0.195856019855 +0.997534513474 0.0701774954796 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999743521214 0.0226437654346 +0.998559653759 0.0536524839699 +0.995607793331 0.0936213210225 +0.990192890167 0.139707162976 +0.970686793327 0.240347534418 +0.946483790874 0.322751075029 +0.868000864983 0.49656188488 +0.761709272861 0.647918403149 +0.63926845789 0.768983185291 +0.494219154119 0.869337022305 +0.343531876802 0.939140737057 +0.207743361592 0.978182911873 +0.102745324373 0.994707226753 +0.0343558080494 0.999409198761 +-0.00151760852896 0.999998629093 +-0.0145966876298 0.999893188477 +-0.0151456221938 0.999884903431 +-0.0106792431325 0.999942779541 +-0.00526315253228 0.999985873699 +-0.000483578070998 0.999999582767 +0.00331365037709 0.999993979931 +0.00622931914404 0.999980211258 +0.00846026558429 0.999963641167 +0.0101777855307 0.999947667122 +0.0115003641695 0.999933302402 +0.0123883727938 0.999922692776 +0.00552844814956 0.999984562397 +-0.0420001894236 0.999117195606 +-0.0264426767826 0.999649763107 +0.0111191393808 0.999937772751 +0.0164693053812 0.999863684177 +0.032898362726 0.999457597733 +0.0231214556843 0.999732136726 +0.0117470920086 0.999930262566 +0.00952063687146 0.999954283237 +0.0074135879986 0.999971985817 +0.00466046994552 0.999988675117 +0.00123130145948 0.999998688698 +-0.00276379822753 0.999995648861 +-0.00705433264375 0.999974668026 +-0.0111785111949 0.999937176704 +-0.0142238344997 0.999898076057 +-0.0140160610899 0.999901235104 +-0.00580701977015 0.999982535839 +0.0185539890081 0.999827444553 +0.0693313851953 0.997593462467 +0.154766008258 0.98795068264 +0.275546371937 0.961287498474 +0.421318918467 0.906912267208 +0.574577093124 0.818450093269 +0.714460372925 0.699675440788 +0.823891639709 0.566746771336 +0.900908350945 0.434009104967 +0.958106935024 0.286410361528 +0.978542268276 0.206045389175 +0.997462570667 0.0711913779378 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999694764614 0.0247025545686 +0.998375117779 0.0569840669632 +0.995317816734 0.0966556817293 +0.989835441113 0.142217636108 +0.969686150551 0.244352862239 +0.9447696805 0.32773411274 +0.862224817276 0.506525039673 +0.753232777119 0.657753765583 +0.628370046616 0.777913808823 +0.481933385134 0.876207470894 +0.331612378359 0.94341558218 +0.198035731912 0.980194211006 +0.0964604392648 0.995336651802 +0.0316875688732 0.99949747324 +-0.00124109059107 0.999998807907 +-0.0124382916838 0.999922215939 +-0.0120711391792 0.999926567078 +-0.00729245087132 0.999972641468 +-0.00181114685256 0.999997496605 +0.0030013367068 0.999994933605 +0.00688284961507 0.999976098537 +0.00994444638491 0.999950051308 +0.0123643968254 0.999923110008 +0.0142895877361 0.999897420406 +0.0158168002963 0.999874413013 +0.0166062284261 0.999861299992 +-0.0034834947437 0.999993503094 +-0.0667947083712 0.997766315937 +-0.0492214858532 0.998787164688 +0.0125498920679 0.999920725822 +0.0246909875423 0.999694406986 +0.0477855913341 0.998856782913 +0.0382226929069 0.999268651009 +0.0172190126032 0.999850928783 +0.0137752918527 0.999904096127 +0.0114999273792 0.999933421612 +0.00859463121742 0.999962687492 +0.00503757409751 0.999986886978 +0.000938279787078 0.999999046326 +-0.00344418711029 0.999993741512 +-0.00769659550861 0.999970018864 +-0.0110528916121 0.999938488007 +-0.011665975675 0.999931275845 +-0.00527536170557 0.99998575449 +0.015860253945 0.999873638153 +0.0620737858117 0.998071074486 +0.142420455813 0.989805936813 +0.259005397558 0.965875446796 +0.402865260839 0.915259122849 +0.557347118855 0.830279588699 +0.70036226511 0.713787317276 +0.813585340977 0.581445217133 +0.893832325935 0.44840079546 +0.954487323761 0.298250794411 +0.976660132408 0.214789226651 +0.99745965004 0.0712326318026 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99963080883 0.0271714441478 +0.998164534569 0.0605604797602 +0.994993329048 0.0999405160546 +0.989398241043 0.145227193832 +0.968553602695 0.248803764582 +0.942881762981 0.333127081394 +0.856274068356 0.516521394253 +0.744887053967 0.667190253735 +0.617900550365 0.786256074905 +0.470475316048 0.882412493229 +0.320898383856 0.947113394737 +0.189734116197 0.981835365295 +0.0915127396584 0.995803654194 +0.0300614628941 0.999547839165 +-0.000320589868352 0.999999523163 +-0.0100094834343 0.999949514866 +-0.00900075491518 0.999959051609 +-0.0040801144205 0.99999153614 +0.00136554881465 0.999998629093 +0.00614484865218 0.99998062849 +0.0100569827482 0.999948918819 +0.0132144782692 0.99991196394 +0.0157749522477 0.99987500906 +0.0178613122553 0.999839961529 +0.0195500832051 0.999808251858 +0.0201776102185 0.999795734882 +-0.00897569768131 0.999959051609 +-0.0519301891327 0.99865013361 +-0.0460519306362 0.998938262463 +0.0160998925567 0.999869704247 +0.0269645266235 0.999635756016 +0.0338658876717 0.999425828457 +0.0321456938982 0.999482452869 +0.0208760518581 0.999781489372 +0.0174137018621 0.999848008156 +0.0150038655847 0.999886870384 +0.011990878731 0.999927759171 +0.0083583695814 0.999964356422 +0.00421844050288 0.999990880489 +-0.000178034155397 0.999999582767 +-0.00445047020912 0.999989748001 +-0.00794025603682 0.999967813492 +-0.00904949847609 0.999958515167 +-0.00391703145579 0.999991834164 +0.0148212760687 0.999889731407 +0.0574700906873 0.998346686363 +0.133664935827 0.991026103497 +0.246628180146 0.969109714031 +0.388580948114 0.921414315701 +0.543809950352 0.839207947254 +0.689024031162 0.724738121033 +0.805150508881 0.593070089817 +0.887908935547 0.460018903017 +0.951406240463 0.30793762207 +0.975069880486 0.221896708012 +0.997519552708 0.0703896284103 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999560236931 0.0296509321779 +0.997961521149 0.0638178735971 +0.994705915451 0.102761544287 +0.989019095898 0.147786930203 +0.967588961124 0.25252956152 +0.941280603409 0.337624669075 +0.851010501385 0.525147974491 +0.737923741341 0.674883306026 +0.609288036823 0.792948722839 +0.461221694946 0.887284457684 +0.31247395277 0.949925899506 +0.183500856161 0.983019292355 +0.0881784185767 0.996104300022 +0.0295118354261 0.999564290047 +0.00120642699767 0.999998867512 +-0.00728857237846 0.999972879887 +-0.00578595465049 0.999982774258 +-0.0007485516835 0.99999922514 +0.00470065604895 0.999988555908 +0.00950805004686 0.999954402447 +0.013513263315 0.999908208847 +0.0168224871159 0.999858140945 +0.0195719897747 0.999807953835 +0.0218609012663 0.999760866165 +0.023746419698 0.999717533588 +0.0244664847851 0.999699950218 +-0.00215238914825 0.999997258186 +-0.0182581841946 0.999832928181 +-0.0219120141119 0.999759376049 +0.022817986086 0.999738931656 +0.0258967392147 0.999663949013 +0.0232677198946 0.999728679657 +0.0285322647542 0.999592065811 +0.0247123911977 0.999693930149 +0.0215280503035 0.999767720699 +0.0189005080611 0.999820768833 +0.0157295633107 0.999875605106 +0.0119668068364 0.999928116798 +0.00772789539769 0.999969601631 +0.00325891771354 0.999994397163 +-0.00108114280738 0.999998927116 +-0.0047038407065 0.999988436699 +-0.00618596700951 0.999980509281 +-0.00196442892775 0.99999755621 +0.015015212819 0.999886751175 +0.0549893155694 0.998486638069 +0.127982184291 0.991775870323 +0.238043740392 0.971253991127 +0.378318279982 0.925675332546 +0.533959805965 0.845509588718 +0.680583953857 0.732669889927 +0.79877269268 0.601632416248 +0.883315980434 0.468777656555 +0.948970973492 0.315363138914 +0.973838448524 0.227240696549 +0.99764496088 0.0685896351933 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999478638172 0.0322849266231 +0.997754812241 0.0669706165791 +0.994423031807 0.105464316905 +0.98863196373 0.150355368853 +0.966652274132 0.256091952324 +0.939726650715 0.341926693916 +0.846085906029 0.533045947552 +0.731856584549 0.681457936764 +0.601966738701 0.798520803452 +0.453600168228 0.891204953194 +0.305835813284 0.95208388567 +0.178951501846 0.983857691288 +0.0862125009298 0.996276557446 +0.0299246553332 0.999551773071 +0.00333099113777 0.999993979931 +-0.00421535409987 0.999990701675 +-0.00233512953855 0.999996840954 +0.00279413443059 0.999995529652 +0.00826972071081 0.999965429306 +0.0131447436288 0.999913215637 +0.0172858666629 0.999850094318 +0.0207883473486 0.999783396721 +0.023764686659 0.999717354774 +0.0262903273106 0.999653935432 +0.0284018740058 0.999595820904 +0.0294656120241 0.999565064907 +0.0100587783381 0.999948918819 +-0.000365934509318 0.999998986721 +-0.000659151643049 0.999999284744 +0.0296559277922 0.99955958128 +0.0262021496892 0.999656140804 +0.060361456126 0.998175859451 +0.0621808767319 0.998063564301 +0.0293562095612 0.999567806721 +0.0261222086847 0.999658167362 +0.0232073981315 0.99972987175 +0.0198388490826 0.999802589417 +0.0159041378647 0.999873101711 +0.0115244016051 0.99993288517 +0.00694367289543 0.999975562096 +0.00250610848889 0.999996244907 +-0.00124620157294 0.999998807907 +-0.00301021314226 0.999994754791 +0.00056078954367 0.999998927116 +0.0162837132812 0.999866962433 +0.0543117746711 0.99852335453 +0.124917328358 0.992166996002 +0.23273076117 0.972540795803 +0.371582955122 0.928399324417 +0.527425885201 0.849600672722 +0.674786984921 0.73801201582 +0.794289946556 0.607538461685 +0.879967570305 0.475033283234 +0.947135448456 0.320833146572 +0.972940385342 0.231055110693 +0.997811198235 0.0661272108555 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999385595322 0.0350453257561 +0.997546613216 0.0700057074428 +0.994142889977 0.108073681593 +0.988232910633 0.152955204248 +0.965740203857 0.259510368109 +0.938210010529 0.346066117287 +0.84152418375 0.540218830109 +0.726655781269 0.687001168728 +0.595853328705 0.803092896938 +0.447454333305 0.894306182861 +0.300763458014 0.953698396683 +0.175838366151 0.984418809414 +0.0853852033615 0.996347725391 +0.0311220940202 0.999515295029 +0.00593741750345 0.999981880188 +-0.00085266365204 0.999999403954 +0.00132328248583 0.999998509884 +0.0065382765606 0.999978244305 +0.0120702134445 0.999926626682 +0.0170544106513 0.99985396862 +0.0213738847524 0.999771058559 +0.0251086205244 0.999684393406 +0.0283464919776 0.999597609043 +0.0311384890229 0.999514579773 +0.0335005037487 0.999438226223 +0.0348939709365 0.999390780926 +0.018874835223 0.99982136488 +0.00477624498308 0.999987900257 +0.00921485945582 0.999956786633 +0.0360572561622 0.999349057674 +0.0427129231393 0.999086618423 +0.0533854775131 0.99857288599 +0.0435768924654 0.999049127102 +0.0406714454293 0.999171555042 +0.0312475897372 0.999510347843 +0.0279268883169 0.999609231949 +0.0243275035173 0.999703645706 +0.0201856791973 0.999795675278 +0.0156311504543 0.999877274036 +0.0109059177339 0.999939799309 +0.00634198263288 0.999979138374 +0.00244770757854 0.999996602535 +0.000413569883676 0.999999523163 +0.00336405448616 0.999993801117 +0.0181900132447 0.999834120274 +0.0551445931196 0.998477697372 +0.124288521707 0.992245495319 +0.230575159192 0.973054230213 +0.368339896202 0.92969083786 +0.524246275425 0.85156661272 +0.671757042408 0.74077129364 +0.791814446449 0.610761165619 +0.877951681614 0.478748828173 +0.945949912071 0.324312061071 +0.972401916981 0.233310952783 +0.998008310795 0.0630808398128 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999281585217 0.0378986001015 +0.997338175774 0.0729150176048 +0.993863642216 0.110612146556 +0.98781979084 0.155602380633 +0.964850783348 0.262797176838 +0.936724185944 0.350067645311 +0.837416231632 0.546564996243 +0.722321331501 0.691557168961 +0.590920329094 0.806729376316 +0.442715466022 0.896661996841 +0.297143995762 0.95483237505 +0.174018338323 0.984742045403 +0.0855506658554 0.996333360672 +0.0329810641706 0.999455630779 +0.00893944688141 0.999959588051 +0.00274798925966 0.999996125698 +0.0052028214559 0.999985873699 +0.0109241111204 0.999939799309 +0.0167090501636 0.999859750271 +0.021332859993 0.999771773815 +0.0265710670501 0.999646365643 +0.0351804532111 0.999380290508 +0.0373109728098 0.999303162098 +0.0367106534541 0.999325454235 +0.0390201061964 0.999237954617 +0.0405978113413 0.999174952507 +0.0254687387496 0.999674856663 +0.0223331563175 0.999749779701 +0.0191015154123 0.999817073345 +0.0425073355436 0.99909555912 +0.0750850960612 0.997176468372 +0.0240410771221 0.999709844589 +-0.0118230739608 0.999929070473 +0.0717313438654 0.997422575951 +0.0467828698456 0.998903810978 +0.055937025696 0.998433530331 +0.0802900493145 0.996770858765 +0.0671000033617 0.99774569273 +0.0596276149154 0.998219907284 +0.0556840933859 0.998447835445 +0.0389649681747 0.999239623547 +0.0170577932149 0.999853551388 +0.00489054247737 0.999987483025 +0.00469957105815 0.999988436699 +0.0181417129934 0.999834835529 +0.0561139620841 0.998423993587 +0.125387266278 0.992107510567 +0.230809926987 0.972998380661 +0.367759913206 0.929920315742 +0.523662745953 0.851925194263 +0.670920431614 0.741529166698 +0.790957808495 0.611870408058 +0.877049267292 0.480399549007 +0.945311367512 0.326168715954 +0.972174584866 0.234255537391 +0.998220205307 0.0596339032054 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999166965485 0.040807146579 +0.997130870819 0.0756942108274 +0.993583858013 0.113097503781 +0.987410187721 0.158180311322 +0.964029729366 0.265793770552 +0.935345232487 0.353735655546 +0.833879947662 0.551945030689 +0.71904361248 0.694964766502 +0.587391972542 0.809302330017 +0.439607530832 0.898189723492 +0.295162349939 0.955446660519 +0.173614069819 0.984813272953 +0.0867653340101 0.996228337288 +0.0355088077486 0.999369084835 +0.0123197911307 0.999923884869 +0.00646953796968 0.999978721142 +0.0110585074872 0.999938189983 +0.0381613001227 0.999271035194 +0.0527053251863 0.998609602451 +0.0309639647603 0.999519944191 +0.0768146067858 0.997044622898 +0.322977691889 0.946406126022 +0.264111578465 0.964491546154 +0.0746321305633 0.99721044302 +0.0468604788184 0.998900651932 +0.0434801578522 0.999053478241 +-0.0153469014913 0.999881863594 +-0.0665081515908 0.997784852982 +-0.00467974646017 0.999988138676 +0.0479645729065 0.998848438263 +0.102422177792 0.994739830494 +0.280973106623 0.959714651108 +0.442427247763 0.896803081036 +0.522237837315 0.852798700333 +0.400151342154 0.916447818279 +0.591506659985 0.806299030781 +0.828352451324 0.56020617485 +0.729487419128 0.683993279934 +0.699927330017 0.714212477207 +0.70849853754 0.705710828304 +0.585543632507 0.81064003706 +0.29560354352 0.955310285091 +0.0558494664729 0.998438417912 +0.00522706145421 0.999985635281 +0.0121259633452 0.999926030636 +0.0549095794559 0.998490869999 +0.127813175321 0.991797983646 +0.233340665698 0.972394585609 +0.369750738144 0.929130792618 +0.525575876236 0.850746452808 +0.672173380852 0.740393280983 +0.79160284996 0.611035466194 +0.877130925655 0.480250239372 +0.945142924786 0.326657056808 +0.972213149071 0.234096825123 +0.998450696468 0.0556415878236 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999043345451 0.0437305904925 +0.996926605701 0.0783410593867 +0.993302643299 0.115540996194 +0.986958384514 0.160975292325 +0.963175773621 0.268871694803 +0.933890342712 0.357558906078 +0.830509901047 0.557003200054 +0.716062068939 0.69803583622 +0.584282457829 0.811549842358 +0.437013506889 0.899454534054 +0.293726205826 0.955889344215 +0.173711851239 0.984796404839 +0.0883880704641 0.996085762978 +0.0383406504989 0.999264061451 +0.0159280374646 0.999872565269 +0.00982537027448 0.999951183796 +0.0212384369224 0.999773800373 +0.152593612671 0.988288283348 +0.214826732874 0.976651251316 +0.0598535686731 0.998206377029 +0.300227880478 0.953866839409 +0.880788207054 0.473509162664 +0.847621500492 0.530600368977 +0.510581254959 0.85982888937 +0.165513172746 0.986207067966 +0.0454061329365 0.998967528343 +-0.135745882988 0.990742981434 +-0.201877325773 0.97940993309 +-0.0369315370917 0.999317348003 +0.0542392767966 0.998527109623 +0.188830494881 0.98200905323 +0.853301465511 0.521415770054 +0.992766141891 0.120058983564 +0.998510539532 0.0545446798205 +0.999996483326 0.00226940377615 +0.995370745659 -0.0960981845856 +0.99982714653 -0.0185479130596 +0.999869942665 0.0160879008472 +0.997880637646 0.0650589838624 +0.976529598236 0.215377628803 +0.787037849426 0.616903662682 +0.532584905624 0.846375405788 +0.301326185465 0.95352011919 +0.0235558450222 0.999721825123 +0.00995890703052 0.999949812889 +0.0546684190631 0.99850410223 +0.13141579926 0.991326630116 +0.23732252419 0.971430242062 +0.373294860125 0.927712380886 +0.528938949108 0.848659574986 +0.674602329731 0.738181114197 +0.793058633804 0.609144866467 +0.877817988396 0.478993177414 +0.94522356987 0.326422840357 +0.97238689661 0.233373254538 +0.998665928841 0.0516346395016 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998912334442 0.0466271489859 +0.996725916862 0.0808539241552 +0.993019938469 0.117946140468 +0.986493766308 0.163798347116 +0.962358355522 0.271783322096 +0.93247795105 0.36122611165 +0.827641844749 0.561255931854 +0.713869690895 0.700277864933 +0.58220499754 0.813041508198 +0.435595482588 0.900141954422 +0.293444126844 0.955975949764 +0.174777314067 0.984607815742 +0.0906966030598 0.995878279209 +0.0415783897042 0.999134838581 +0.0197364818305 0.999804735184 +0.0136364037171 0.999906659126 +0.0226669982076 0.999742090702 +0.132780656219 0.991144537926 +0.261768609285 0.96512979269 +0.104670062661 0.99450647831 +0.219582617283 0.975593268871 +0.807435452938 0.589955210686 +0.864772677422 0.502162098885 +0.838915109634 0.544261753559 +0.712995529175 0.701167404652 +0.206852391362 0.97837138176 +-0.117268279195 0.99309951067 +-0.129293292761 0.991605460644 +-0.0249822381884 0.999687194824 +0.0609656050801 0.998139321804 +0.145268559456 0.98939114809 +0.740485608578 0.672070920467 +0.985154271126 0.171666905284 +0.998783767223 0.0492755658925 +0.999728441238 -0.0232573989779 +0.997664093971 -0.0682984888554 +0.998470664024 0.0552713051438 +0.958960473537 0.283536374569 +0.942197263241 0.335056781769 +0.935182034969 0.354165047407 +0.646624624729 0.762807548046 +0.14984357357 0.988708615303 +0.219847679138 0.975532889366 +0.0422651953995 0.999105870724 +0.0143114207312 0.99989682436 +0.0594514235854 0.998230516911 +0.137368023396 0.990519344807 +0.243704155087 0.969849228859 +0.379554659128 0.925168931484 +0.534956812859 0.8448792696 +0.679269134998 0.73388916254 +0.796149373055 0.605099618435 +0.879613757133 0.475688070059 +0.945852458477 0.324596315622 +0.972860813141 0.231389954686 +0.998870849609 0.0475047677755 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.9987834692 0.049310747534 +0.996545314789 0.0830501168966 +0.992762804031 0.12009139359 +0.986061751842 0.16637904942 +0.961660265923 0.27424249053 +0.931223332882 0.364448875189 +0.825390040874 0.564562261105 +0.712463021278 0.701708734035 +0.581084132195 0.813843131065 +0.435203611851 0.900331556797 +0.294121921062 0.955767333508 +0.176619753242 0.984278678894 +0.0935472920537 0.995614409447 +0.0451430007815 0.9989798069 +0.0237226095051 0.999718248844 +0.0181524790823 0.999834537506 +0.0234195981175 0.999724924564 +0.119370609522 0.992848992348 +0.297372430563 0.95476102829 +-0.885275065899 0.465066939592 +-0.794368267059 0.607434511185 +0.998140454292 0.0609412677586 +0.941810548306 -0.336141318083 +0.936152160168 -0.35159316659 +0.776232004166 0.630446016788 +0.577351987362 0.816494345665 +-0.297884166241 0.954600811005 +-0.583542943001 0.812081694603 +-0.985294699669 0.170859485865 +-0.9060100317 -0.423254281282 +0.996173858643 0.0873884707689 +0.997009694576 -0.0772645547986 +0.580914676189 0.813963353634 +0.472071826458 0.881558954716 +0.557203054428 0.830375254154 +0.46018114686 0.887823820114 +-0.76408714056 0.645111858845 +-0.944368898869 -0.328886717558 +0.999994575977 0.00301604159176 +0.998669326305 0.0515474751592 +0.219935238361 0.975513577461 +0.00287076993845 0.999995052814 +0.0652074217796 0.997870624065 +0.0367558784783 0.999323546886 +0.0204522609711 0.99979019165 +0.0667809844017 0.997767329216 +0.144923552871 0.989442408085 +0.251815497875 0.967774927616 +0.387709081173 0.921781420708 +0.542769908905 0.839880883694 +0.685416698456 0.728150844574 +0.800306856632 0.599590182304 +0.882132649422 0.47100019455 +0.946819484234 0.321764647961 +0.973515927792 0.228617444634 +0.999049663544 0.0435864664614 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.9986577034 0.0517941303551 +0.99638402462 0.0849631726742 +0.992533862591 0.12196906656 +0.985678017139 0.168637394905 +0.961132109165 0.276088148355 +0.930236160755 0.366961270571 +0.823610007763 0.567156136036 +0.711597084999 0.702586770058 +0.580620884895 0.814173519611 +0.435507655144 0.900184869766 +0.295434862375 0.955362558365 +0.178960457444 0.983856022358 +0.0967338308692 0.995309948921 +0.0489041395485 0.998803079128 +0.0278050359339 0.999612510204 +0.0225638467818 0.999745070934 +0.0263903364539 0.999651193619 +0.111907839775 0.993717730045 +0.314703732729 0.949188947678 +0.290097355843 0.95699608326 +0.110004507005 0.993930399418 +0.0597712285817 0.998211324215 +0.0855641663074 0.99633204937 +0.21080969274 0.977526366711 +0.457296937704 0.889312684536 +0.18256521225 0.983193337917 +-0.321930319071 0.946762502193 +-0.321043044329 0.947063863277 +0.0442458949983 0.999019861221 +0.0789834707975 0.996875524521 +0.0785445868969 0.996910333633 +0.0821287855506 0.996621310711 +0.140588358045 0.990067243576 +-0.0215287636966 0.999767363071 +0.129166200757 0.991621851921 +0.166368812323 0.986062645912 +0.0626956224442 0.998031318188 +0.0528684556484 0.998600423336 +0.0466958060861 0.998908698559 +0.0412100404501 0.99914932251 +0.0158515311778 0.999873161316 +-0.0800616592169 0.996788859367 +-0.0468643344939 0.998900473118 +0.0156452395022 0.999876737595 +0.0230164788663 0.999734282494 +0.0716487020254 0.997429251671 +0.152013942599 0.988377690315 +0.259670734406 0.965696930885 +0.395517975092 0.918457746506 +0.550166130066 0.835054934025 +0.691172063351 0.722689986229 +0.804150104523 0.594425797462 +0.884459733963 0.466615498066 +0.947621881962 0.319393604994 +0.974078178406 0.226210221648 +0.999176859856 0.0405633710325 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998534500599 0.0541175119579 +0.996233820915 0.0867061689496 +0.992314398289 0.123739987612 +0.985305905342 0.170799016953 +0.96069508791 0.277605503798 +0.929374575615 0.369137197733 +0.822560548782 0.568676888943 +0.711605846882 0.702578365803 +0.581258177757 0.813718736172 +0.437024980783 0.899448812008 +0.29790943861 0.954593777657 +0.182258531451 0.983250439167 +0.100594736636 0.994927167892 +0.053068138659 0.99859046936 +0.0320829041302 0.999484777451 +0.0265679638833 0.999646484852 +0.0272364094853 0.999627888203 +0.0562676042318 0.998414933681 +0.26383665204 0.964566707611 +0.349619209766 0.936891138554 +0.211263820529 0.977428197861 +0.0730008557439 0.997331082821 +0.0753066763282 0.997159838676 +0.0832775011659 0.996525943279 +0.0501613281667 0.998740494251 +-0.143747314811 0.989613950253 +-0.158873707056 0.987298130989 +-0.103049680591 0.994675457478 +0.0784092098475 0.996920228004 +0.0860717073083 0.996288478374 +0.0842870771885 0.996440649033 +0.0602318458259 0.998183727264 +-0.0989464819431 0.995091855526 +-0.432127654552 0.901811182499 +-0.109207816422 0.994018435478 +0.171503350139 0.985182404518 +0.0533959679306 0.998572528362 +0.0524247810245 0.998624205589 +0.0334636680782 0.999439001083 +0.0102060530335 0.999947071075 +-0.0162565987557 0.999866843224 +-0.0552963018417 0.998469173908 +-0.0456313453615 0.998957335949 +0.0147313140333 0.999890327454 +0.0270579569042 0.999633193016 +0.0779395401478 0.996957540512 +0.161043167114 0.986946880817 +0.269859582186 0.962899148464 +0.405851900578 0.913938522339 +0.55992937088 0.828540205956 +0.698863446712 0.71525478363 +0.809395968914 0.587262690067 +0.887718617916 0.460385769606 +0.948922276497 0.315508157015 +0.974897146225 0.222654312849 +0.999285042286 0.0378039516509 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998416900635 0.0562455020845 +0.996097028255 0.088265106082 +0.992109894753 0.125371366739 +0.984954893589 0.172811150551 +0.960386693478 0.278670310974 +0.928702354431 0.370825916529 +0.822185635567 0.569218933582 +0.712347745895 0.701825737953 +0.582789003849 0.812623262405 +0.439494967461 0.898244738579 +0.301261752844 0.953540921211 +0.186250954866 0.982501804829 +0.104921765625 0.994480133057 +0.0574935860932 0.99834549427 +0.0365226641297 0.999332249165 +0.0294281560928 0.999566316605 +-0.0633798986673 0.997988939285 +-0.380551248789 0.924758851528 +-0.0511767528951 0.998688817024 +0.72437363863 0.689405858517 +0.599972844124 0.800019621849 +0.992331147194 -0.123605012894 +0.987985432148 0.154542043805 +0.399130702019 0.916893184185 +0.12818646431 0.991749346256 +-0.984395563602 0.175966560841 +0.999641954899 -0.0267293807119 +0.244974032044 0.969528853893 +0.106461457908 0.994316220284 +-0.997398555279 -0.0720722824335 +0.946528434753 0.322618037462 +-0.251463860273 0.967865824699 +-0.664434015751 0.747345864773 +-0.798844873905 0.601535379887 +0.769780576229 0.638307452202 +0.0630080476403 0.998012185097 +-0.0638735815883 0.99795717001 +-0.96139895916 0.275156497955 +-0.474824994802 0.880079329014 +-0.745222330093 0.666814565659 +-0.364300101995 0.931280434132 +0.0105996793136 0.999942719936 +-0.128684729338 0.991684138775 +-0.0126579692587 0.999919116497 +0.0333067961037 0.999444305897 +0.0867805182934 0.996227264404 +0.170898139477 0.985288262367 +0.280629396439 0.959815561771 +0.416741997004 0.90902453661 +0.570166289806 0.821528732777 +0.706891834736 0.707321107388 +0.814871430397 0.579641163349 +0.891134560108 0.453738361597 +0.950282633305 0.311387121677 +0.975733757019 0.218958705664 +0.999359130859 0.0357906855643 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998308062553 0.0581459403038 +0.995975911617 0.0896212458611 +0.991925299168 0.12682273984 +0.984662473202 0.174470186234 +0.960254669189 0.2791249156 +0.928302109241 0.371826350689 +0.82254087925 0.568705558777 +0.713867068291 0.700280725956 +0.585258245468 0.810846269131 +0.442956417799 0.896542787552 +0.305519759655 0.952185094357 +0.190949976444 0.981599390507 +0.109709613025 0.993963062763 +0.062158420682 0.998065888882 +0.0410368666053 0.999156951904 +0.0281466562301 0.999602913857 +-0.27335947752 0.961911082268 +-0.119194991887 0.992870211601 +-0.464182287455 0.885738909245 +0.81382727623 0.581105411053 +0.889630436897 0.456679552794 +0.996931016445 -0.0782749727368 +0.990701854229 0.1360450387 +0.759817183018 0.650134503841 +-0.654290497303 0.756241738796 +-0.999728739262 -0.023253403604 +0.864823937416 0.502073764801 +0.500123977661 0.865953147411 +-0.204285189509 0.97891074419 +-0.917050480843 0.398769587278 +0.88321262598 0.468970268965 +0.33403518796 0.942559540272 +-0.436313688755 0.899794101715 +-0.990259170532 -0.139230370522 +0.99196010828 -0.126540020108 +-0.0198054704815 0.99980276823 +-0.117373086512 0.993087351322 +-0.994306087494 0.106555692852 +-0.980384767056 0.19708929956 +0.219703808427 0.975565612316 +-0.678138196468 0.734932780266 +0.0922751426697 0.995732963085 +-0.151884615421 0.988397181034 +-0.0207939073443 0.999782264233 +0.0408510714769 0.999164581299 +0.0966188758612 0.99532097578 +0.18105918169 0.983471512794 +0.291583061218 0.956545054913 +0.427703410387 0.903918385506 +0.580374777317 0.8143491745 +0.714778900146 0.69935041666 +0.820214748383 0.57205504179 +0.894429385662 0.44720813632 +0.951549053192 0.30749553442 +0.976500034332 0.215515077114 +0.99940007925 0.0346266068518 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998210847378 0.0597899742424 +0.995873510838 0.0907511711121 +0.991768062115 0.128046959639 +0.984383225441 0.176038086414 +0.960195362568 0.279328882694 +0.927996337414 0.372588455677 +0.823254346848 0.567672252655 +0.715619027615 0.698490440845 +0.587978303432 0.808876097202 +0.446644514799 0.894710898399 +0.309939175844 0.950756072998 +0.195718973875 0.980659842491 +0.114475913346 0.9934258461 +0.0667292922735 0.997770547867 +0.045409951359 0.998967766762 +0.0370917767286 0.999311089516 +-0.0623135752976 0.998055875301 +0.158658534288 0.987332701683 +-0.0609787628055 0.998138010502 +0.193130970001 0.981171965599 +0.745262086391 0.666770875454 +0.932564735413 0.361000418663 +0.94343572855 0.331552833319 +0.902412354946 0.430871874094 +0.625304043293 0.780379712582 +0.215527832508 0.976496934891 +0.453778803349 0.891113340855 +0.33517241478 0.942156076431 +0.27496650815 0.961453378201 +0.112923875451 0.993602693081 +0.022235635668 0.999752283096 +0.162253931165 0.986748278141 +-0.0403653644025 0.999184370041 +-0.0213870275766 0.999770700932 +0.0710029378533 0.997475504875 +-0.108291178942 0.994118690491 +-0.202142760158 0.979355275631 +-0.0673485994339 0.997728765011 +-0.564472317696 0.825450837612 +-0.848701775074 0.528870463371 +-0.418911218643 0.90802615881 +0.132946848869 0.991122364998 +0.0536364167929 0.99855953455 +0.0362263992429 0.999343037605 +0.0473878830671 0.99887573719 +0.105689056218 0.994398832321 +0.191050320864 0.981579780579 +0.302397370338 0.953181564808 +0.438431382179 0.898764491081 +0.590285658836 0.807193696499 +0.72232490778 0.691553294659 +0.82529848814 0.56469643116 +0.897590339184 0.440829873085 +0.952727377415 0.303825438023 +0.977195799351 0.212338000536 +0.999408900738 0.034376822412 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998128414154 0.061152074486 +0.995793282986 0.0916273891926 +0.991645634174 0.128992065787 +0.984168112278 0.177237421274 +0.960333824158 0.278851896524 +0.928009331226 0.372556507587 +0.824600338936 0.565715432167 +0.717971682549 0.696071624756 +0.5913875103 0.806387007236 +0.451011747122 0.892517983913 +0.314913183451 0.949120283127 +0.200832813978 0.979625403881 +0.11934582144 0.992852210999 +0.0711842477322 0.997462630272 +0.0494898110628 0.998774111271 +0.0451351068914 0.998980045319 +0.111025825143 0.993816673756 +0.52809381485 0.849184989929 +0.540395200253 0.841410338879 +0.284158140421 0.958776652813 +0.300785928965 0.953690707684 +0.586907148361 0.809652626514 +0.723478078842 0.690346717834 +0.711224377155 0.70296394825 +0.282508939505 0.959263622761 +0.114056654274 0.993473351002 +0.198320358992 0.980136632919 +0.205119743943 0.978736162186 +0.162956342101 0.986632287502 +0.0107814827934 0.999940633774 +0.134757697582 0.99087780714 +0.426877856255 0.90430867672 +0.336649417877 0.941629290581 +0.128222644329 0.991744458675 +0.0456592477858 0.998956084251 +-0.278419882059 0.960458636284 +-0.335933923721 0.941884756088 +-0.137835219502 0.990454137325 +-0.189730867743 0.981835007668 +-0.327774167061 0.944754719734 +-0.32794085145 0.944697499275 +0.0740504711866 0.997253537178 +0.059609234333 0.998220324516 +0.0495541505516 0.998770356178 +0.0523062571883 0.998629808426 +0.113237962127 0.993567466736 +0.200365364552 0.979720830917 +0.312555283308 0.949899375439 +0.448411136866 0.893827080727 +0.599425792694 0.80042976141 +0.729166030884 0.684335708618 +0.829867899418 0.557959318161 +0.900412142277 0.435037314892 +0.953689754009 0.300791442394 +0.977752685547 0.209758788347 +0.999384820461 0.0350680761039 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998063027859 0.0622101910412 +0.995738506317 0.0922196730971 +0.99156576395 0.129603385925 +0.984031319618 0.177994981408 +0.960627257824 0.277840077877 +0.928269565105 0.371907889843 +0.826494991779 0.562943279743 +0.720815956593 0.693125605583 +0.595350384712 0.803465664387 +0.455916136503 0.890022337437 +0.320321440697 0.947308421135 +0.206216618419 0.978506028652 +0.124306991696 0.992243528366 +0.0755792781711 0.997139215469 +0.0534077435732 0.998572051525 +0.0597167536616 0.998214781284 +0.31673887372 0.948512256145 +0.771409153938 0.636337637901 +0.934069514275 0.357089847326 +0.946063995361 0.323976516724 +0.952612698078 0.30418330431 +0.930403411388 0.366535604 +0.803554713726 0.595229566097 +0.502717614174 0.864449739456 +0.20543435216 0.978670358658 +0.112944468856 0.993600785732 +0.108057044446 0.994143784046 +-0.0454280078411 0.998966872692 +-0.585022866726 0.81101578474 +-0.970105290413 0.242679417133 +-0.426291048527 0.904585242271 +0.576565265656 0.817050278187 +0.398191869259 0.917301058769 +0.217307895422 0.976102232933 +-0.132975995541 0.991118729115 +-0.546316683292 0.837578177452 +-0.810624599457 0.585565567017 +-0.939610123634 0.342244386673 +-0.96475559473 0.263144701719 +-0.977859914303 0.209257006645 +-0.848903715611 0.528546094894 +0.000891449453775 0.999998807907 +0.0940757095814 0.995563864708 +0.061010543257 0.998136281967 +0.0568774230778 0.998380720615 +0.120158821344 0.992753922939 +0.209264606237 0.97785872221 +0.322104424238 0.946703493595 +0.457665890455 0.889123737812 +0.607794344425 0.794094264507 +0.735313475132 0.67772680521 +0.833934366703 0.551863133907 +0.902901351452 0.429847151041 +0.954515337944 0.298161238432 +0.978218793869 0.207574337721 +0.999326646328 0.0366894714534 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998016893864 0.0629461407661 +0.995712935925 0.092496983707 +0.991536617279 0.129826545715 +0.98398733139 0.178237736225 +0.961131513119 0.276090532541 +0.928886890411 0.37036305666 +0.829029262066 0.55920445919 +0.724293410778 0.689491152763 +0.600037515163 0.799971401691 +0.461535871029 0.887121140957 +0.326318830252 0.945259034634 +0.211973443627 0.977274894714 +0.129390642047 0.991593241692 +0.0798683986068 0.996805131435 +0.0570443049073 0.998371481895 +0.0920116305351 0.995757341385 +0.52509701252 0.851041734219 +0.293586462736 0.955931663513 +0.635764062405 0.771882474422 +0.930143237114 0.367194354534 +0.989936888218 0.14150634408 +0.958862900734 0.283867329359 +0.999867975712 -0.0162092000246 +0.986551523209 0.163447588682 +0.720562696457 0.693388581276 +0.212153449655 0.977235138416 +-0.030014809221 0.99954855442 +-0.958215594292 0.286044567823 +-0.996269345284 0.0862876549363 +-0.999914765358 -0.0129861859605 +0.861184597015 -0.508290588856 +0.825999796391 0.563668549061 +0.239723786712 0.970840632915 +0.120159700513 0.992753684521 +-0.465250104666 0.885178387165 +-0.674084484577 0.738653659821 +-0.99948066473 0.0322018116713 +-0.999998629093 0.00109091494232 +-0.997384548187 0.0722689852118 +-0.975649118423 0.219334244728 +-0.399688154459 0.916650116444 +0.108236476779 0.994124352932 +0.129061475396 0.991635501385 +0.0764123499393 0.997075498104 +0.0616223067045 0.998098790646 +0.126711174846 0.99193918705 +0.217451363802 0.976070761681 +0.330468177795 0.943816721439 +0.465623348951 0.884982705116 +0.614876627922 0.78862285614 +0.740385830402 0.672181725502 +0.83724039793 0.546834647655 +0.90490013361 0.42562314868 +0.955077111721 0.296356648207 +0.978545367718 0.206029370427 +0.999231517315 0.0391945838928 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998001456261 0.0631899163127 +0.99573802948 0.0922260954976 +0.991623103619 0.129164561629 +0.984153330326 0.17731936276 +0.962063014507 0.272826910019 +0.930229663849 0.366977572441 +0.832750678062 0.553647279739 +0.729162395 0.68434035778 +0.606353282928 0.795194625854 +0.468829065561 0.883288264275 +0.333798646927 0.942643761635 +0.218828529119 0.9757630229 +0.135104134679 0.990831077099 +0.0843470394611 0.996435940266 +0.0605276785791 0.99816608429 +0.070594497025 0.997504711151 +0.301462769508 0.953477084637 +0.226760953665 0.973949551582 +0.222847923636 0.974852442741 +0.259378105402 0.965775310993 +0.416839808226 0.908979296684 +0.506491661072 0.862244069576 +0.695039749146 0.718970417976 +0.852752685547 0.522313475609 +0.846454739571 0.532459139824 +0.253686308861 0.967285990715 +-0.224218800664 0.974538266659 +-0.308138847351 0.951340317726 +-0.537127673626 0.843499898911 +-0.648883163929 0.760887205601 +-0.170571729541 0.985344529152 +0.23490087688 0.972018420696 +-0.0174961090088 0.999846041203 +-0.0900458022952 0.995937108994 +-0.440130919218 0.897932469845 +-0.402556717396 0.915394186974 +-0.210388109088 0.977616906166 +-0.237677484751 0.971342980862 +-0.176444381475 0.984310269356 +-0.0750040337443 0.997182130814 +0.0427589192986 0.999084353447 +0.0977096036077 0.995213508606 +0.0983028486371 0.995155394077 +0.0700308158994 0.997543931007 +0.0658310577273 0.997830152512 +0.13335211575 0.99106836319 +0.224836573005 0.974395871162 +0.33767002821 0.941264033318 +0.47232568264 0.881423950195 +0.620727181435 0.784026145935 +0.744448065758 0.667679846287 +0.83983528614 0.542840719223 +0.906419217587 0.422378510237 +0.955350160599 0.295474231243 +0.978720724583 0.205193951726 +0.999096155167 0.0425042919815 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998025357723 0.0628127455711 +0.995832502842 0.0912004858255 +0.991807103157 0.12774476409 +0.98449587822 0.175407022238 +0.963375687599 0.268154919147 +0.932239532471 0.361841380596 +0.837515890598 0.546412348747 +0.735273480415 0.677769303322 +0.614133000374 0.789201676846 +0.47763890028 0.878555953503 +0.34263420105 0.939468562603 +0.226700022817 0.973963975906 +0.141411170363 0.989950478077 +0.0890168175101 0.996029913425 +0.0638867765665 0.997956871986 +0.0580961667001 0.99831032753 +0.106120608747 0.994352400303 +0.15341566503 0.988161027431 +0.155839592218 0.987781047821 +0.101225659251 0.994862914085 +0.119936659932 0.992780864239 +0.121829688549 0.992550313473 +0.143544778228 0.989643454552 +0.243795081973 0.969825863838 +0.27261197567 0.962123274803 +0.0939470082521 0.995576560497 +-0.0368746928871 0.999319374561 +-0.0103118214756 0.999946057796 +-0.107314579189 0.994224309921 +0.0690811350942 0.997610032558 +0.0915914401412 0.995796084404 +0.032389126718 0.999474167824 +-0.248706936836 0.968577802181 +-0.214492633939 0.976725041866 +-0.0266973115504 0.999642252922 +0.0233908575028 0.999725699425 +0.0697552859783 0.997563481331 +0.0751063302159 0.997174918652 +0.0787475630641 0.996893644333 +0.0777862295508 0.996969521046 +0.0737473145127 0.997276008129 +0.047448925674 0.998872220516 +-0.0130733409896 0.99991351366 +0.048867687583 0.99880439043 +0.074320666492 0.997233867645 +0.14168445766 0.98991137743 +0.230786547065 0.973003804684 +0.343289256096 0.939229488373 +0.477382898331 0.878695130348 +0.625054657459 0.780580401421 +0.747301280499 0.664484977722 +0.84159052372 0.540115356445 +0.907431960106 0.42019879818 +0.955324113369 0.295559227467 +0.978740274906 0.205102145672 +0.99891769886 0.0465101860464 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998073875904 0.0620352439582 +0.995967388153 0.0897157937288 +0.992068231106 0.125699460506 +0.984980762005 0.172663941979 +0.964965343475 0.262377381325 +0.934759557247 0.355280548334 +0.843041479588 0.537847697735 +0.742315649986 0.670049369335 +0.623043477535 0.782186567783 +0.487669289112 0.873027920723 +0.352623581886 0.935764610767 +0.235507532954 0.971872091293 +0.148340895772 0.988935947418 +0.0939760282636 0.995574116707 +0.0672401860356 0.997736334801 +0.0592700913548 0.998241782188 +0.0973398089409 0.995250344276 +0.342856675386 0.939386725426 +0.438939601183 0.898515880108 +0.302195191383 0.953245580196 +0.709217429161 0.704988539219 +0.609158456326 0.793047487736 +0.378410637379 0.925636589527 +0.329716056585 0.944079220295 +0.171392813325 0.985202014446 +0.107143700123 0.994242370129 +0.223317876458 0.974744796753 +0.271888703108 0.962327778339 +0.0937858819962 0.995591461658 +0.0941583290696 0.995556235313 +0.0629218965769 0.998017787933 +-0.231744989753 0.972775757313 +-0.498990625143 0.866606354713 +-0.580666661263 0.814140677452 +-0.542987704277 0.83973968029 +-0.315301030874 0.948991060257 +-0.342607945204 0.939477682114 +-0.208139792085 0.978098154068 +0.0321599952877 0.999481797218 +0.0701211243868 0.997537434101 +0.0675570368767 0.997714519501 +-6.40043872409e-05 0.99999910593 +-0.0835248976946 0.996504604816 +0.025511585176 0.999673545361 +0.0908529087901 0.995863497257 +0.151498436928 0.988457024097 +0.23536722362 0.971905946732 +0.347375839949 0.937725305557 +0.480812698603 0.876822650433 +0.627815842628 0.778361320496 +0.748911440372 0.662669599056 +0.842474639416 0.538735330105 +0.907882869244 0.41922301054 +0.954971730709 0.296696156263 +0.97858774662 0.20582832396 +0.998694658279 0.0510783866048 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998143911362 0.0608992837369 +0.996137201786 0.0878104269505 +0.992397487164 0.123073883355 +0.985592007637 0.169139936566 +0.966779828072 0.255610108376 +0.937724113464 0.34738060832 +0.849248230457 0.527993261814 +0.750262200832 0.661139845848 +0.633097112179 0.774071633816 +0.498986005783 0.866609454155 +0.36388105154 0.931444883347 +0.245385825634 0.969424962997 +0.156015351415 0.987754225731 +0.0993182510138 0.995055496693 +0.0707392543554 0.997494459152 +0.0616227313876 0.998098909855 +0.10896088928 0.994045376778 +0.576451361179 0.817130923271 +0.80945032835 0.587186455727 +0.869616091251 0.493726611137 +0.987889170647 0.155154392123 +0.984973967075 0.172697201371 +0.956070780754 0.293134123087 +0.923185586929 0.384351551533 +0.749553978443 0.661942601204 +0.389455586672 0.921044051647 +0.271916508675 0.962319970131 +0.353677272797 0.935366392136 +0.208220005035 0.978080451488 +0.053319837898 0.998575925827 +-0.221184268594 0.97523111105 +-0.0273532308638 0.99962490797 +-0.419309824705 0.907841801643 +-0.906507313251 0.422187238932 +-0.974291205406 0.225288569927 +-0.996199369431 0.0870933458209 +-0.993984818459 -0.109509669244 +-0.999752283096 0.0222017187625 +-0.635821819305 0.771834731102 +-0.303571760654 0.952807962894 +-0.181865796447 0.983321905136 +-0.293888896704 0.955838620663 +-0.415439218283 0.909619987011 +-0.0996314138174 0.995023190975 +0.0921753793955 0.995741724968 +0.157361134887 0.987540721893 +0.238602533937 0.971116900444 +0.34997689724 0.936757922173 +0.482631713152 0.87582296133 +0.628968060017 0.777430713177 +0.749223470688 0.662317156792 +0.842422068119 0.538817644119 +0.907711744308 0.419592618942 +0.95425349474 0.298997282982 +0.978238046169 0.207483515143 +0.998423457146 0.0561260506511 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99823319912 0.0594175644219 +0.996339142323 0.085486985743 +0.992789566517 0.119869761169 +0.986321210861 0.164834320545 +0.968792915344 0.247871264815 +0.941100239754 0.338127523661 +0.8560795784 0.516843318939 +0.75910705328 0.650965094566 +0.64431899786 0.764756143093 +0.511658787727 0.859188556671 +0.376517504454 0.926409184933 +0.25647187233 0.966551423073 +0.164568036795 0.986365437508 +0.131428912282 0.991325259209 +0.33568328619 0.941974580288 +0.679637074471 0.733547866344 +0.969152569771 0.246459454298 +0.996577322483 0.0826547369361 +0.999989271164 -0.00447045685723 +0.999997437 -0.00185027788393 +0.999258995056 0.0384643822908 +0.995641469955 0.0932560265064 +0.976298868656 0.21642242372 +0.946583867073 0.322454750538 +0.916473269463 0.400094151497 +0.87519288063 0.483772575855 +0.358387172222 0.933572232723 +0.286229401827 0.958160042763 +0.189596787095 0.981861412525 +-0.247595727444 0.968861997128 +-0.520675241947 0.853752791882 +-0.00792251527309 0.999967753887 +0.0629204437137 0.998017132282 +-0.444287180901 0.895883202553 +-0.988747417927 0.149587839842 +-0.992359817028 0.123369537294 +-0.999453485012 -0.0330185070634 +-0.988412976265 -0.151783168316 +-0.980096518993 -0.198517203331 +-0.997979521751 -0.0635214373469 +-0.987352848053 0.15852932632 +-0.957532644272 0.288321942091 +-0.855565428734 0.517692625523 +-0.334933042526 0.942240893841 +0.0019658037927 0.999997258186 +0.152310058475 0.988332152367 +0.240893036127 0.970551252365 +0.351259469986 0.936277747154 +0.482928663492 0.875659227371 +0.628533303738 0.777782082558 +0.748227357864 0.663441717625 +0.841407001019 0.54040145874 +0.906894147396 0.42135733366 +0.953153610229 0.30248516798 +0.977679252625 0.210100620985 +0.998092532158 0.061734367162 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998338997364 0.0576114691794 +0.996569335461 0.0827613696456 +0.993236601353 0.116107262671 +0.987154006958 0.159770712256 +0.970968186855 0.239208221436 +0.944835364819 0.327545315027 +0.863376557827 0.504559695721 +0.768694043159 0.639616429806 +0.656536340714 0.754293739796 +0.525527954102 0.850775837898 +0.390420615673 0.920635938644 +0.268713980913 0.963219583035 +0.174001947045 0.984745085239 +0.239127233624 0.970987558365 +0.971644341946 0.236444815993 +0.999333262444 0.0364993624389 +0.997835755348 -0.0657475143671 +0.999983906746 -0.00554479472339 +0.999833524227 -0.0181945990771 +0.998851418495 -0.0478934124112 +0.998751878738 -0.049927894026 +0.999935805798 0.0112634012476 +0.999586880207 -0.0286990962923 +0.998361766338 -0.0571984313428 +0.999158918858 -0.0409888289869 +0.999991178513 -0.0039689312689 +0.275783270597 0.961218953133 +0.233302220702 0.972403049469 +0.0897854566574 0.995960116386 +-0.391560047865 0.920151054859 +-0.315657168627 0.948872208595 +-0.0538060367107 0.998550593853 +3.14369026455e-05 0.999998629093 +-0.170123830438 0.985421657562 +-0.980461835861 0.196703121066 +-0.992693662643 0.120652474463 +-0.999665439129 0.0258354358375 +-0.999903440475 -0.01380587928 +-0.999984800816 0.00531385652721 +-0.999679088593 -0.0252980068326 +-0.999871492386 -0.015991827473 +-0.999982714653 0.0057085333392 +-0.994257390499 0.107007667422 +-0.893366277218 0.449327945709 +-0.487315177917 0.873225212097 +-0.110940329731 0.993826329708 +0.15134806931 0.988479912281 +0.350335240364 0.936623930931 +0.481328397989 0.876540124416 +0.626152217388 0.77970045805 +0.745652973652 0.666334092617 +0.839258313179 0.543732106686 +0.90534299612 0.424679994583 +0.95164513588 0.307198286057 +0.976890325546 0.213740363717 +0.997706472874 0.0676870495081 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998457968235 0.0555112548172 +0.996821761131 0.0796635001898 +0.99372780323 0.111825890839 +0.988070964813 0.153998821974 +0.973286747932 0.229592248797 +0.948865830898 0.315679341555 +0.871067106724 0.491163134575 +0.779048025608 0.626963794231 +0.669823884964 0.742519378662 +0.540733098984 0.841194093227 +0.405786782503 0.913967311382 +0.282334685326 0.959315657616 +0.184517160058 0.982828855515 +0.11958976835 0.992823004723 +0.0923252105713 0.995728373528 +0.0815103128552 0.996672034264 +0.0789123401046 0.996880948544 +0.655779480934 0.754951775074 +0.976788043976 -0.214204341173 +0.947206735611 -0.320621073246 +0.914135932922 0.4054056108 +0.344019144773 0.938961386681 +0.349525004625 0.93692612648 +0.325017869473 0.945707559586 +0.217570796609 0.976043879986 +0.162830665708 0.986653208733 +0.0807870477438 0.996730387211 +0.180478096008 0.983578145504 +0.102405823767 0.994741201401 +-0.0780827179551 0.996945798397 +-0.0757738724351 0.997123599052 +0.0309294518083 0.9995200634 +4.21626191383e-06 0.999998688698 +0.0171575639397 0.999851703644 +-0.583082020283 0.812411785126 +-0.998784482479 0.0492796301842 +-0.999998927116 3.28143069055e-05 +-0.999999046326 3.72727095055e-06 +-0.999998986721 1.45967496792e-05 +-0.999997615814 -0.00175522069912 +-0.999761581421 -0.0218093227595 +-0.999928772449 -0.0118542537093 +-0.99999910593 0.000243138172664 +-0.999944508076 0.0104652121663 +-0.851673483849 0.524071455002 +-0.251992583275 0.967728495598 +-0.0753063932061 0.997160077095 +0.345755636692 0.938324153423 +0.478331059217 0.878178834915 +0.622342050076 0.782745420933 +0.741936743259 0.670469343662 +0.836294293404 0.548280000687 +0.903264403343 0.429083317518 +0.949819684029 0.312796741724 +0.975901186466 0.218211919069 +0.99726742506 0.0738764032722 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998586237431 0.0531561523676 +0.9970895648 0.0762382224202 +0.9942497015 0.107086598873 +0.989047288895 0.147598966956 +0.975637257099 0.21938970685 +0.95305365324 0.302800804377 +0.879037261009 0.476752489805 +0.790000557899 0.613105416298 +0.684000849724 0.729480624199 +0.557121157646 0.830430448055 +0.422538280487 0.906344413757 +0.297362804413 0.954764306545 +0.196262225509 0.980551123619 +0.126264676452 0.991996049881 +0.0857328996062 0.996317565441 +0.0672305524349 0.997736990452 +0.06184989959 0.998084902763 +0.0921833589673 0.995741546154 +0.186631426215 0.982429385185 +0.0928224176168 0.995682179928 +0.0696556195617 0.997570574284 +0.0666855350137 0.997773587704 +0.0643843188882 0.997924506664 +0.0607532374561 0.998152136803 +0.0561540536582 0.998421669006 +0.0510709919035 0.99869453907 +0.0529600456357 0.998596131802 +0.20680321753 0.978382050991 +0.233993157744 0.972237467766 +0.293008208275 0.956108987331 +0.148892253637 0.988852202892 +-0.104825235903 0.9944896698 +0.0474782958627 0.998871266842 +0.167347729206 0.985897183418 +-0.510784089565 0.859708428383 +-0.989053010941 0.147556245327 +-0.999983906746 0.0055849198252 +-0.999997437 0.00184532627463 +-0.999994754791 0.00305947032757 +-0.999999046326 -0.000785212730989 +-0.999862372875 -0.0165632274002 +-0.999995410442 -0.00287497905083 +-0.999727964401 0.0232872404158 +-0.997190237045 0.0749055743217 +-0.766340732574 0.642433226109 +-0.20062597096 0.979667425156 +-0.00203692121431 0.999997258186 +0.344832450151 0.938663959503 +0.474977135658 0.879997730255 +0.618042528629 0.786144316196 +0.737820982933 0.674995958805 +0.833034992218 0.553220272064 +0.900989830494 0.433839827776 +0.947939813137 0.318448096514 +0.974849402905 0.222862571478 +0.996799886227 0.0799369141459 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998717010021 0.0506396666169 +0.997371315956 0.0724590048194 +0.994800329208 0.101844698191 +0.99008077383 0.140498399734 +0.978057324886 0.208335116506 +0.957444489002 0.288616806269 +0.887386143208 0.4610260427 +0.801793754101 0.597600638866 +0.699439525604 0.714691400528 +0.575205981731 0.818008005619 +0.441298693419 0.897359907627 +0.314462989569 0.949269473553 +0.209849357605 0.977733314037 +0.135520532727 0.990774333477 +0.0908611342311 0.995863080025 +0.0690241754055 0.997614741325 +0.0611729696393 0.998126924038 +0.0599460080266 0.998201310635 +0.0607802607119 0.99815094471 +0.0614426955581 0.998110294342 +0.0609951168299 0.998137950897 +0.0590856969357 0.99825245142 +0.0556817539036 0.998448073864 +0.0509976856411 0.998698413372 +0.0454361476004 0.998966991901 +0.0395071469247 0.99921888113 +0.0415353029966 0.99913662672 +0.349222093821 0.937039673328 +0.743402957916 0.668842971325 +0.225517019629 0.974238157272 +-0.0491821095347 0.998788893223 +-0.332177728415 0.943216383457 +0.0120197813958 0.999927163124 +0.0875035375357 0.996163368225 +-0.157250612974 0.987558066845 +-0.594774663448 0.803891599178 +-0.858209252357 0.513299405575 +-0.911532044411 0.411227732897 +-0.897443890572 0.441127985716 +-0.890195012093 0.455578625202 +-0.884430587292 0.466670483351 +-0.847120165825 0.531400799751 +-0.76416695118 0.645017683506 +-0.612249612808 0.790663897991 +-0.202143877745 0.979355096817 +0.140999600291 0.990009367466 +0.260145992041 0.965568780899 +0.346206486225 0.938158154488 +0.471998184919 0.881599366665 +0.613976716995 0.789324104786 +0.733914792538 0.679241240025 +0.829931974411 0.557864189148 +0.898838460445 0.438279092312 +0.946167469025 0.323676645756 +0.973822951317 0.227307677269 +0.996340334415 0.0854741558433 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998848855495 0.0479687526822 +0.997639119625 0.0686723291874 +0.99532443285 0.096587382257 +0.991066813469 0.133365705609 +0.980360329151 0.197213813663 +0.961695611477 0.274119287729 +0.895560264587 0.444939643145 +0.813610613346 0.581409394741 +0.715112805367 0.699008464813 +0.593845307827 0.804579019547 +0.460958659649 0.887421429157 +0.332703411579 0.943031132221 +0.224620595574 0.974446117878 +0.145808368921 0.989312410355 +0.0967516601086 0.995308160782 +0.0712942481041 0.997455000877 +0.0607445053756 0.998152673244 +0.0575229004025 0.998343884945 +0.0567773170769 0.998386383057 +0.0560816563666 0.998425602913 +0.0544088631868 0.998518288136 +0.0513704493642 0.998679101467 +0.0469208844006 0.998898208141 +0.0412810333073 0.999147236347 +0.0348759554327 0.999391198158 +0.0282382685691 0.99960064888 +0.0244034025818 0.999701738358 +0.13444635272 0.990920007229 +0.465615779161 0.884985983372 +0.130289018154 0.991475522518 +-0.270362585783 0.962757885456 +-0.300972700119 0.953631997108 +-0.0858124122024 0.996310889721 +0.00889718532562 0.999959826469 +-0.00187858799472 0.999997675419 +-0.0594733320177 0.998229444027 +-0.12932755053 0.991601169109 +-0.154091015458 0.988056063652 +-0.133777782321 0.991010725498 +-0.116845823824 0.993149399757 +-0.101125843823 0.99487298727 +-0.0704177469015 0.997517168522 +-0.0288786832243 0.999582350254 +0.0216211602092 0.99976593256 +0.101489067078 0.994836449623 +0.173316314816 0.984865665436 +0.246556028724 0.969128191471 +0.3463139534 0.93811827898 +0.470133334398 0.882595181465 +0.610904872417 0.791703641415 +0.730833590031 0.68255507946 +0.827445566654 0.561545550823 +0.897080421448 0.44186642766 +0.944653868675 0.328068345785 +0.972898602486 0.231230556965 +0.995917618275 0.090266443789 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998977959156 0.0451972708106 +0.997902154922 0.0647393465042 +0.995839953423 0.0911195799708 +0.992038667202 0.125933140516 +0.982610285282 0.185679644346 +0.965901494026 0.258909314871 +0.903753340244 0.428053021431 +0.82581949234 0.563934206963 +0.731500089169 0.681840777397 +0.613608300686 0.789610207081 +0.482152193785 0.876087069511 +0.352757751942 0.935714244843 +0.241258352995 0.9704605937 +0.157784208655 0.98747330904 +0.104000844061 0.994576931 +0.0745488703251 0.997216939926 +0.060964141041 0.998139739037 +0.0554843470454 0.998459100723 +0.0529653355479 0.998596072197 +0.0507809482515 0.998709440231 +0.0478188171983 0.998855471611 +0.0436561964452 0.999046504498 +0.0382264554501 0.999268651009 +0.0317406579852 0.99949580431 +0.0246268603951 0.999696314335 +0.0174250807613 0.999847650528 +0.01077462174 0.999941527843 +0.00996353011578 0.999950110912 +0.0453598089516 0.998969852924 +0.0015694090398 0.999997973442 +-0.297535270452 0.954710304737 +-0.251964390278 0.967736124992 +-0.0502060614526 0.998738527298 +0.00130388245452 0.999998748302 +0.00821863859892 0.999965846539 +0.0157763026655 0.999875247478 +0.0260108541697 0.999661564827 +0.0396949537098 0.99921143055 +0.0569987148046 0.998373925686 +0.0766872540116 0.997054755688 +0.0959875434637 0.995382189751 +0.111769713461 0.99373370409 +0.122900336981 0.992418825626 +0.132662281394 0.991160869598 +0.14960193634 0.988746106625 +0.185492962599 0.982644975185 +0.25053524971 0.968107163906 +0.347790777683 0.937572002411 +0.469954252243 0.882690548897 +0.609344899654 0.792905032635 +0.728979110718 0.684535861015 +0.825835645199 0.563910365105 +0.895890772343 0.444274008274 +0.943511366844 0.331339389086 +0.972141802311 0.234391525388 +0.995534896851 0.0943922922015 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999101400375 0.042382504791 +0.99815350771 0.0607412755489 +0.996333420277 0.0855540558696 +0.992971479893 0.118353702128 +0.98475331068 0.173955872655 +0.969922721386 0.243412598968 +0.911748707294 0.410747379065 +0.838109493256 0.545501172543 +0.748226523399 0.663442850113 +0.634119808674 0.773234128952 +0.504576027393 0.863366782665 +0.374443143606 0.927249491215 +0.259708017111 0.965686917305 +0.171492159367 0.985185205936 +0.112711057067 0.993627429008 +0.0789236575365 0.996880412102 +0.0619884207845 0.998076498508 +0.0539974085987 0.998540759087 +0.0495095290244 0.998773336411 +0.0456926785409 0.998955190182 +0.0413572788239 0.999144256115 +0.0360584557056 0.999349415302 +0.0297059249133 0.999558329582 +0.0224831774831 0.999746739864 +0.0147975869477 0.99989014864 +0.00717651331797 0.999973773956 +0.000150976062287 0.999999523163 +-0.00593709340319 0.999981999397 +-0.0256173778325 0.999671220779 +-0.215230405331 0.976562678814 +-0.348433077335 0.937333345413 +-0.167658284307 0.985844790936 +-0.0202538203448 0.999794363976 +-0.00824970193207 0.99996560812 +-0.00225745141506 0.999997019768 +0.00580575456843 0.999982953072 +0.0169840138406 0.99985563755 +0.0322395414114 0.999480068684 +0.0518745370209 0.998653113842 +0.0745911821723 0.997214078903 +0.0972582548857 0.995258748531 +0.116151832044 0.993230998516 +0.12952631712 0.991575598717 +0.140280410647 0.990111649036 +0.156951859593 0.987605690956 +0.191630646586 0.981466710567 +0.254978060722 0.966946601868 +0.350493490696 0.936564803123 +0.471187382936 0.88203305006 +0.609149336815 0.79305523634 +0.728280723095 0.685278654099 +0.825077295303 0.56501942873 +0.895262241364 0.445539057255 +0.942743778229 0.333517074585 +0.971561908722 0.236782729626 +0.995220720768 0.0976489931345 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99921631813 0.0395806990564 +0.998387873173 0.0567582249641 +0.996794641018 0.080002643168 +0.993844866753 0.110780157149 +0.986761748791 0.162175804377 +0.973698616028 0.227838993073 +0.919596195221 0.392864406109 +0.85057246685 0.525856494904 +0.765456736088 0.64348679781 +0.655631840229 0.755080282688 +0.528567790985 0.848890841007 +0.398156613111 0.917317032814 +0.280375540257 0.959890007973 +0.187299743295 0.982302486897 +0.123190872371 0.992382466793 +0.084667801857 0.996408641338 +0.06402451545 0.99794781208 +0.0532466173172 0.998581051826 +0.046582903713 0.998913943768 +0.040975023061 0.999159812927 +0.0351605564356 0.999381363392 +0.0286893825978 0.999588131905 +0.0214520171285 0.999769508839 +0.0135873612016 0.999907314777 +0.00545499660075 0.999984681606 +-0.00245446595363 0.999996781349 +-0.00964113511145 0.999953091145 +-0.0164393782616 0.999864578247 +-0.0613024495542 0.998118877411 +-0.293036192656 0.956100523472 +-0.344281196594 0.938865959644 +-0.11900626123 0.992892980576 +-0.0237619280815 0.999717116356 +-0.018013317138 0.999837398529 +-0.0120928166434 0.999926507473 +-0.00367848481983 0.999992966652 +0.00825876928866 0.999965667725 +0.0248737446964 0.999690413475 +0.0466068647802 0.998913049698 +0.0721135735512 0.997396230698 +0.0979386642575 0.995192229748 +0.119807630777 0.992796957493 +0.135424360633 0.99078732729 +0.147396251559 0.989076972008 +0.164308264852 0.986408889294 +0.198522269726 0.980095922947 +0.261003047228 0.965337693691 +0.355461061001 0.934690952301 +0.475028991699 0.879970014095 +0.611502051353 0.791242480278 +0.729730427265 0.683734714985 +0.825908124447 0.563804149628 +0.895690977573 0.444676250219 +0.942632734776 0.333830803633 +0.971324384212 0.237755998969 +0.995004057884 0.0998343154788 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999320983887 0.0368445776403 +0.998601615429 0.0528655275702 +0.997215628624 0.0745710656047 +0.994644105434 0.103358149529 +0.988568603992 0.150770753622 +0.977100849152 0.212775796652 +0.927010476589 0.375034302473 +0.862694323063 0.505725383759 +0.782444655895 0.622719585896 +0.677189528942 0.735808193684 +0.553065955639 0.833137094975 +0.422882378101 0.906183838844 +0.302427947521 0.953172028065 +0.204613745213 0.978842496872 +0.135058894753 0.990837454796 +0.0915521681309 0.995799839497 +0.0669427141547 0.997756719589 +0.0531748756766 0.998584866524 +0.0441865883768 0.999022960663 +0.0366727225482 0.999326944351 +0.0292967464775 0.99957048893 +0.0216218866408 0.99976593256 +0.0135305123404 0.999908149242 +0.00510467030108 0.999986588955 +-0.00336910691112 0.999994039536 +-0.0114618726075 0.999933838844 +-0.0187185816467 0.999824464321 +-0.0251624397933 0.999683082104 +-0.048277951777 0.998833477497 +-0.164492219687 0.986378073692 +-0.178502440453 0.983938932419 +-0.0521664731205 0.998638033867 +-0.0310337096453 0.999517858028 +-0.0272210091352 0.999628782272 +-0.0212998595089 0.999772906303 +-0.0126386033371 0.999919891357 +-7.20213211025e-05 0.999999880791 +0.0177163910121 0.999842762947 +0.0412642769516 0.999148070812 +0.0691650509834 0.997604906559 +0.0976848453283 0.995217144489 +0.122124135494 0.992514550686 +0.13980512321 0.990178883076 +0.153176650405 0.988198637962 +0.170911252499 0.985285997391 +0.205557644367 0.978644907475 +0.268178999424 0.963368713856 +0.36243095994 0.932010054588 +0.481345504522 0.876530408859 +0.616359829903 0.787464141846 +0.733325242996 0.679877817631 +0.828340351582 0.5602247715 +0.897188961506 0.441645890474 +0.943242013454 0.332105666399 +0.97146987915 0.237161949277 +0.99491751194 0.100693263113 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999414145947 0.0342211462557 +0.998792290688 0.0491305552423 +0.99759209156 0.0693543553352 +0.995360136032 0.0962194874883 +0.990178525448 0.139807462692 +0.980136990547 0.198321074247 +0.933957397938 0.357382893562 +0.874292492867 0.485398381948 +0.798923015594 0.601433098316 +0.698437452316 0.715670287609 +0.57765352726 0.816281557083 +0.448192924261 0.893936395645 +0.32547929883 0.945548951626 +0.223122954369 0.97478979826 +0.1480833143 0.988974511623 +0.0994088351727 0.995046317577 +0.0706210210919 0.997502982616 +0.0536952093244 0.998557090759 +0.0422629751265 0.999106168747 +0.0327456742525 0.999463558197 +0.0237225946039 0.999718368053 +0.0147842140868 0.999890506268 +0.00582030089572 0.999982893467 +-0.00314905354753 0.999994635582 +-0.0119281839579 0.999928474426 +-0.020164033398 0.999796271324 +-0.0274538435042 0.999622762203 +-0.0334915108979 0.999438822269 +-0.0393667668104 0.999224364758 +-0.0495201572776 0.998772919178 +-0.0478264652193 0.998855233192 +-0.0409918576479 0.999159097672 +-0.0397148951888 0.999210715294 +-0.0361087173223 0.999347507954 +-0.030217397958 0.999543011189 +-0.0213870797306 0.999770760536 +-0.0083252619952 0.999965310097 +0.0104070212692 0.999945759773 +0.0354109816253 0.999372720718 +0.0652214437723 0.997870504856 +0.0958994477987 0.995390832424 +0.122466340661 0.992472231388 +0.142043054104 0.989860236645 +0.15706153214 0.987588465214 +0.176310122013 0.984334230423 +0.212399274111 0.977182805538 +0.276246458292 0.961086630821 +0.371175438166 0.92856246233 +0.489911794662 0.871771931648 +0.62350332737 0.781820058823 +0.738866329193 0.673851668835 +0.832216262817 0.554450571537 +0.899645924568 0.436619818211 +0.944467663765 0.3286036551 +0.971950113773 0.235186100006 +0.994960308075 0.100269839168 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999495685101 0.0317498594522 +0.998959243298 0.0456101447344 +0.997922062874 0.0644330307841 +0.99598890543 0.0894764959812 +0.991584837437 0.129458576441 +0.98279106617 0.184719711542 +0.940425097942 0.339999854565 +0.885239064693 0.465135514736 +0.814692080021 0.579893648624 +0.719102084637 0.694904029369 +0.602001070976 0.798494875431 +0.473744571209 0.880662024021 +0.349216192961 0.937041699886 +0.242561385036 0.97013604641 +0.162028536201 0.986785888672 +0.108002051711 0.994150578976 +0.074807561934 0.997197747231 +0.0545491650701 0.998511016369 +0.0405751205981 0.9991761446 +0.0289996266365 0.999579131603 +0.0182839781046 0.999832391739 +0.00804522912949 0.999967575073 +-0.00180079624988 0.999998152256 +-0.0112785873935 0.999936044216 +-0.0202891863883 0.999793827534 +-0.0285763014108 0.999591469765 +-0.0358083955944 0.999358177185 +-0.0416990742087 0.999129772186 +-0.0460746698081 0.998937726021 +-0.0488102734089 0.998807728291 +-0.0499118603766 0.99875330925 +-0.0497804991901 0.998760044575 +-0.0480293892324 0.998845875263 +-0.0444202013314 0.999012768269 +-0.0385972820222 0.999254643917 +-0.0296809691936 0.999559223652 +-0.0162776391953 0.999867200851 +0.00313433539122 0.999994874001 +0.0291826259345 0.999573886395 +0.0603426769376 0.998177528381 +0.0925475656986 0.995708048344 +0.120707727969 0.992687880993 +0.141956582665 0.98987275362 +0.158881321549 0.987297594547 +0.180418208241 0.983589708805 +0.219091117382 0.975704193115 +0.285380750895 0.958413779736 +0.381956011057 0.924180328846 +0.501008272171 0.865441977978 +0.633183002472 0.774001896381 +0.746536195278 0.665344655514 +0.837653636932 0.546200990677 +0.903129637241 0.429366677999 +0.94634449482 0.323158591986 +0.972789883614 0.231687679887 +0.995109379292 0.0987791717052 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999565839767 0.0294614899904 +0.999102830887 0.0423487015069 +0.998206138611 0.0598704405129 +0.996531307697 0.0832182466984 +0.9927906394 0.119861312211 +0.985067129135 0.172169879079 +0.946293830872 0.323307365179 +0.895330607891 0.445400804281 +0.829436302185 0.558600902557 +0.738750755787 0.6739782691 +0.625600636005 0.780143022537 +0.499037086964 0.866580426693 +0.373218506575 0.927743017673 +0.262608915567 0.964902281761 +0.176643252373 0.984274506569 +0.117091961205 0.993120610714 +0.0792339146137 0.996855735779 +0.055447075516 0.998461425304 +0.0388577356935 0.999244272709 +0.0252464283258 0.999680936337 +0.0129046672955 0.999916434288 +0.00144929660019 0.999998688698 +-0.00917606242001 0.999957621098 +-0.0190408956259 0.999818563461 +-0.0281525533646 0.999603390694 +-0.0363668017089 0.999338209629 +-0.0434362106025 0.999055862427 +-0.0491328127682 0.99879181385 +-0.0533338040113 0.998576283455 +-0.0560259632766 0.998428761959 +-0.0572490803897 0.99835973978 +-0.0570246428251 0.99837243557 +-0.0552913472056 0.998469889164 +-0.051829982549 0.998655557632 +-0.0461347699165 0.998934864998 +-0.0372406542301 0.99930614233 +-0.0236772391945 0.999719560146 +-0.00388000253588 0.999992251396 +0.0227631554008 0.999740302563 +0.0546635240316 0.998504579067 +0.0877077504992 0.996145904064 +0.116875901818 0.993146419525 +0.139540970325 0.990215957165 +0.158610314131 0.987341046333 +0.183175057173 0.983080029488 +0.22549431026 0.974244236946 +0.295317471027 0.955398857594 +0.394366055727 0.918953001499 +0.514122843742 0.857716202736 +0.644854426384 0.76430529356 +0.755850195885 0.65474396944 +0.844279944897 0.535901844501 +0.907387375832 0.420294910669 +0.948714315891 0.316133290529 +0.973908662796 0.226939246058 +0.995356678963 0.0962539091706 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999629497528 0.027215667069 +0.999233663082 0.0391419678926 +0.99846559763 0.0553748905659 +0.997028172016 0.0770367830992 +0.993879497051 0.110468558967 +0.987124085426 0.159955501556 +0.951968669891 0.306194514036 +0.905371069908 0.424620270729 +0.84436494112 0.535768151283 +0.75905328989 0.651028335094 +0.650548994541 0.759464025497 +0.526435434818 0.850214660168 +0.399880111217 0.916567265987 +0.285441696644 0.958395600319 +0.193702489138 0.981060147285 +0.127992630005 0.99177479744 +0.0848128348589 0.996396541595 +0.0570333451033 0.998371779919 +0.0376274548471 0.999291479588 +0.021976461634 0.999758303165 +0.00808590278029 0.999967157841 +-0.00450286921114 0.999989509583 +-0.0158353019506 0.999874413013 +-0.0260122008622 0.999661147594 +-0.0351402871311 0.999382257462 +-0.0431936345994 0.999066472054 +-0.0500207319856 0.998747825623 +-0.0554602481425 0.998460531235 +-0.0594373494387 0.998231828213 +-0.0619741640985 0.998077392578 +-0.0631344616413 0.998004674911 +-0.0629486143589 0.998016417027 +-0.061346039176 0.998116374016 +-0.0580765157938 0.998311817646 +-0.0525785759091 0.998616635799 +-0.0438150130212 0.999039411545 +-0.0302574187517 0.9995418787 +-0.0103386668488 0.999946475029 +0.0164851751179 0.999863982201 +0.0485459491611 0.998820841312 +0.0817704573274 0.996651053429 +0.111418299377 0.993773460388 +0.135369583964 0.990794956684 +0.157040804625 0.987591981888 +0.185665786266 0.982612550259 +0.232995212078 0.97247761488 +0.307658553123 0.951496720314 +0.410057574511 0.912059605122 +0.530766248703 0.847518146038 +0.659709393978 0.751520633698 +0.767653405666 0.640864789486 +0.85265237093 0.522477865219 +0.912756383419 0.408503621817 +0.951764166355 0.306829661131 +0.975408911705 0.220401480794 +0.995706915855 0.0925614833832 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999684631824 0.0251119006425 +0.999347031116 0.0361317619681 +0.998691141605 0.0511443205178 +0.997461795807 0.071201890707 +0.994830369949 0.101550400257 +0.988936960697 0.148336142302 +0.95730304718 0.289085954428 +0.915114045143 0.403193414211 +0.859124243259 0.511766374111 +0.779565751553 0.626319944859 +0.676388800144 0.73654460907 +0.555614829063 0.831439554691 +0.429157227278 0.903229832649 +0.311361253262 0.950291514397 +0.213803693652 0.976876437664 +0.141467154026 0.989942491055 +0.0923454612494 0.995726943016 +0.0600800588727 0.998193383217 +0.03763384372 0.999291360378 +0.0199448484927 0.999800920486 +0.00458896532655 0.999989330769 +-0.00908842496574 0.999958336353 +-0.0211492236704 0.999776005745 +-0.0316883251071 0.999497532845 +-0.040867138654 0.999164164066 +-0.0487615317106 0.998810172081 +-0.0553245432675 0.998467981815 +-0.0604767650366 0.998169362545 +-0.0642005428672 0.997936785221 +-0.0665573775768 0.997782170773 +-0.0676369667053 0.997709929943 +-0.0674837455153 0.997720062733 +-0.0660267621279 0.997817516327 +-0.0629917308688 0.998013734818 +-0.0577640086412 0.998329997063 +-0.0492380484939 0.99878680706 +-0.0358461290598 0.999357163906 +-0.0160633325577 0.999870955944 +0.0105354916304 0.999944329262 +0.042201269418 0.999108731747 +0.0750077217817 0.997182846069 +0.104715831578 0.994501948357 +0.129962027073 0.991518735886 +0.15480697155 0.987944364548 +0.188542932272 0.982064545155 +0.242121487856 0.970245718956 +0.322674572468 0.946509420872 +0.428982645273 0.903312444687 +0.550614714622 0.834759294987 +0.677254915237 0.735748231411 +0.781495809555 0.623910307884 +0.862394213676 0.50623691082 +0.918967723846 0.394332140684 +0.95529961586 0.295638561249 +0.977185964584 0.212384149432 +0.996139168739 0.0877873525023 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999736249447 0.0229663271457 +0.999453365803 0.0330578945577 +0.99890345335 0.0468173883855 +0.997870802879 0.0652217268944 +0.99569773674 0.092660933733 +0.990606248379 0.136744230986 +0.962530612946 0.271170496941 +0.924882829189 0.380251437426 +0.874159455299 0.485638469458 +0.800874173641 0.598831772804 +0.703868508339 0.710329890251 +0.587507843971 0.809218227863 +0.462167680264 0.886792302132 +0.341625183821 0.939835906029 +0.238235265017 0.971207439899 +0.158692583442 0.987327754498 +0.102773182094 0.99470448494 +0.0652423873544 0.997869312763 +0.0392838977277 0.999227881432 +0.0194130558521 0.999811351299 +0.00263126334175 0.999996244907 +-0.0120808547363 0.999926865101 +-0.0248855352402 0.999689817429 +-0.0358593612909 0.999356627464 +-0.0451672784984 0.998979389668 +-0.0529512651265 0.998596906662 +-0.0592636279762 0.998242139816 +-0.0641187205911 0.997942149639 +-0.067569218576 0.997714281082 +-0.0697246268392 0.997565925121 +-0.0707067251205 0.997496783733 +-0.0705812722445 0.99750572443 +-0.0692833513021 0.997596681118 +-0.0665191337466 0.997785151005 +-0.0616251304746 0.998099029064 +-0.0534412190318 0.998570740223 +-0.0403961353004 0.999183654785 +-0.0210584048182 0.999778091908 +0.00484718475491 0.999988019466 +0.0355387404561 0.999367952347 +0.0674033537507 0.99772554636 +0.0969535410404 0.995288550854 +0.123798765242 0.992307066917 +0.152688547969 0.988273859024 +0.192785218358 0.981240570545 +0.253877609968 0.967236101627 +0.341215461493 0.939984798431 +0.451712340117 0.892163515091 +0.573936879635 0.818899393082 +0.697525978088 0.716559231281 +0.797260761261 0.603634536266 +0.873367369175 0.487061589956 +0.925908207893 0.377748012543 +0.959287345409 0.282431423664 +0.97921872139 0.202805429697 +0.996623754501 0.08210349828 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.99978351593 0.0208061821759 +0.99955111742 0.0299595780671 +0.999098539352 0.0424495451152 +0.998247742653 0.0591732896864 +0.996484994888 0.0837701335549 +0.992138326168 0.125144928694 +0.967547059059 0.252690136433 +0.934447944164 0.356098711491 +0.889121294022 0.457670778036 +0.822508275509 0.568752944469 +0.732454121113 0.680816054344 +0.621650099754 0.783294737339 +0.498693645 0.866777896881 +0.376392394304 0.926460146904 +0.267535954714 0.963547468185 +0.180454611778 0.98358297348 +0.116921387613 0.993140876293 +0.0731938928366 0.997317373753 +0.043002218008 0.999074459076 +0.0205756295472 0.999788105488 +0.00226906174794 0.999997138977 +-0.0134705081582 0.999908983707 +-0.027035497129 0.9996342659 +-0.0385158881545 0.999257862568 +-0.0480468645692 0.998844861984 +-0.0557957217097 0.998441755772 +-0.0618965737522 0.998082399368 +-0.0664625167847 0.997788608074 +-0.0696302875876 0.997572720051 +-0.0715689435601 0.997435510159 +-0.0724407434464 0.997372627258 +-0.0723366439342 0.997380077839 +-0.0711980834603 0.997461855412 +-0.0687106847763 0.997636258602 +-0.0641667321324 0.997938930988 +-0.0563729293644 0.998409628868 +-0.0437965616584 0.99904024601 +-0.0251470375806 0.999683558941 +-0.000307804031763 0.999999701977 +0.0289857201278 0.999579548836 +0.0596151538193 0.998221218586 +0.0890651270747 0.996025383472 +0.118052482605 0.993007063866 +0.151952579618 0.988387584686 +0.199527427554 0.979892194271 +0.269037842751 0.963129460812 +0.363546460867 0.931575894356 +0.478001981974 0.87835842371 +0.600124180317 0.799906671047 +0.719770491123 0.69421184063 +0.814253032207 0.580509781837 +0.885033845901 0.465526461601 +0.933212995529 0.359322965145 +0.963471114635 0.267811089754 +0.981367111206 0.192141354084 +0.997129738331 0.0757102742791 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999825894833 0.0186604242772 +0.999638617039 0.0268786940724 +0.999273896217 0.0381004214287 +0.998587012291 0.0531401820481 +0.997184455395 0.0749870315194 +0.993515789509 0.113693013787 +0.97228038311 0.23381640017 +0.943632364273 0.330993592739 +0.90371543169 0.42813295126 +0.844030082226 0.536295175552 +0.761588335037 0.648060619831 +0.657465994358 0.753483772278 +0.538311302662 0.842745780945 +0.415550649166 0.909569859505 +0.301957905293 0.953321218491 +0.20726390183 0.978284835815 +0.135346233845 0.99079811573 +0.0843129828572 0.996439099312 +0.0488547757268 0.998805642128 +0.0231841597706 0.999731063843 +0.00304878479801 0.999995052814 +-0.0137725574896 0.999904990196 +-0.0280718319118 0.999605834484 +-0.0400519743562 0.999197423458 +-0.0498319901526 0.99875742197 +-0.0575781688094 0.998340666294 +-0.0634842142463 0.997982501984 +-0.0677580013871 0.997701585293 +-0.0706285014749 0.99750238657 +-0.0723343938589 0.997380316257 +-0.0730820447206 0.997325658798 +-0.0729842483997 0.997332930565 +-0.0719824284315 0.997405707836 +-0.0697373822331 0.997565090656 +-0.0655081346631 0.997851908207 +-0.0581022575498 0.998310267925 +-0.0460731126368 0.998937904835 +-0.0283013992012 0.999599218369 +-0.00479713175446 0.999988377094 +0.0228796061128 0.999738156796 +0.052308164537 0.998630940914 +0.0821294337511 0.996621549129 +0.114206500351 0.99345690012 +0.154360964894 0.988014340401 +0.210600450635 0.977571964264 +0.289267152548 0.957248210907 +0.390981346369 0.920398533344 +0.508732676506 0.860924363136 +0.629664599895 0.776866734028 +0.744204759598 0.667951405048 +0.832537293434 0.553968310356 +0.897395074368 0.441227406263 +0.940866649151 0.338776230812 +0.967833638191 0.251589804888 +0.983618438244 0.180261313915 +0.997628688812 0.068825148046 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999862849712 0.0165587030351 +0.999715268612 0.023858293891 +0.999427497387 0.0338316895068 +0.99888497591 0.0472093299031 +0.997791469097 0.0664239451289 +0.994728624821 0.102541960776 +0.976622641087 0.214959844947 +0.952187418938 0.305513054132 +0.917513310909 0.397704541683 +0.864766657352 0.502173483372 +0.790325522423 0.612686753273 +0.693807303905 0.720160365105 +0.579859316349 0.814716458321 +0.458183169365 0.888857543468 +0.341022610664 0.940054953098 +0.239108726382 0.970992684364 +0.158343374729 0.987384021282 +0.098933801055 0.995093822479 +0.0569519810379 0.99837654829 +0.0269817542285 0.999635696411 +0.00436004577205 0.999990403652 +-0.0138271776959 0.999904155731 +-0.0289200432599 0.999581515789 +-0.0413797050714 0.999143242836 +-0.0513850487769 0.998678743839 +-0.0591152645648 0.998250901699 +-0.0648139044642 0.997897207737 +-0.068777769804 0.997631847858 +-0.071330152452 0.997452318668 +-0.0727815702558 0.997347772121 +-0.0733769610524 0.997304201126 +-0.0732367560267 0.997314274311 +-0.0722843334079 0.997383892536 +-0.0701499581337 0.997536182404 +-0.0660722926259 0.997814416885 +-0.0588927194476 0.998264014721 +-0.0472936183214 0.998880803585 +-0.0303446948528 0.999539375305 +-0.00813063979149 0.999966740608 +0.0181028209627 0.999836027622 +0.0468121096492 0.998903632164 +0.0779025256634 0.996960818768 +0.114304818213 0.993445396423 +0.161996886134 0.986790955067 +0.227822691202 0.97370249033 +0.315853923559 0.94880759716 +0.42414060235 0.905595958233 +0.543908119202 0.839144587517 +0.662151634693 0.749369561672 +0.77026873827 0.637719333172 +0.851587295532 0.524212360382 +0.910045862198 0.414507597685 +0.948596060276 0.31648850441 +0.972205996513 0.234126552939 +0.985877513885 0.16746763885 +0.998096525669 0.0616702623665 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999894440174 0.0145301120356 +0.999780714512 0.0209406986833 +0.999558627605 0.0297040119767 +0.999139845371 0.0414668954909 +0.998305439949 0.0581911839545 +0.99577409029 0.0918359830976 +0.980514109135 0.19644755125 +0.959958732128 0.280140548944 +0.930231809616 0.366971939802 +0.884239673615 0.467033147812 +0.817944645882 0.575296700001 +0.729731857777 0.683733046055 +0.622317433357 0.782764792442 +0.50343888998 0.864030599594 +0.384298294783 0.923208773136 +0.276098519564 0.961128950119 +0.186500132084 0.982454895973 +0.117909528315 0.993023991585 +0.0681474655867 0.997675061226 +0.0326101183891 0.999467968941 +0.00654508871958 0.999978244305 +-0.013550395146 0.999907970428 +-0.0296461973339 0.999560058117 +-0.0426145344973 0.999091267586 +-0.0528190396726 0.998603999615 +-0.0605140253901 0.998167097569 +-0.0660086795688 0.997818827629 +-0.0696851313114 0.99756872654 +-0.0719539150596 0.997407793999 +-0.0731884613633 0.997317790985 +-0.0736614987254 0.997282862663 +-0.0734892264009 0.99729591608 +-0.072571054101 0.997362852097 +-0.0705127567053 0.997510790825 +-0.066555917263 0.997782468796 +-0.0596080943942 0.998221814632 +-0.0484914518893 0.998823225498 +-0.0324134193361 0.999474406242 +-0.0113953761756 0.999935030937 +0.0138228619471 0.999904215336 +0.0427165292203 0.999087035656 +0.0764195099473 0.997075557709 +0.118660882115 0.992934703827 +0.17514103651 0.984543144703 +0.25111836195 0.967956125736 +0.348162978888 0.937433540821 +0.461845308542 0.886960446835 +0.582020759583 0.813173890114 +0.696055412292 0.717987716198 +0.796670258045 0.604414105415 +0.87045109272 0.492254376411 +0.922359228134 0.386332988739 +0.956024587154 0.293285816908 +0.976375520229 0.216080158949 +0.98803037405 0.154257789254 +0.99851578474 0.0544605478644 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999920606613 0.0126016288996 +0.999834954739 0.0181652531028 +0.999667644501 0.0257741287351 +0.999352037907 0.0359934791923 +0.998734772205 0.0502882152796 +0.996668815613 0.0815549269319 +0.984023213387 0.178038775921 +0.967036426067 0.254636585712 +0.941989719868 0.335641235113 +0.902582168579 0.430516123772 +0.844573318958 0.535439491272 +0.765362679958 0.643598854542 +0.665864944458 0.746072232723 +0.551686763763 0.834051012993 +0.432494550943 0.901636362076 +0.319352954626 0.947635531425 +0.221276044846 0.97521096468 +0.142847374082 0.989744544029 +0.0839556753635 0.996469259262 +0.0412856824696 0.999147236347 +0.0104195121676 0.999945521355 +-0.0125085646287 0.999921560287 +-0.0300931595266 0.999546825886 +-0.0437498092651 0.999042510986 +-0.054181765765 0.998530983925 +-0.0618266686797 0.998086869717 +-0.0671088248491 0.997745454311 +-0.0705073922873 0.997511208057 +-0.0725148841739 0.99736726284 +-0.0735585391521 0.997290730476 +-0.0739297568798 0.99726319313 +-0.0737347900867 0.997277677059 +-0.0728494673967 0.997342765331 +-0.0708633884788 0.997485995293 +-0.0670354440808 0.997750401497 +-0.0603455789387 0.998177409172 +-0.0497255809605 0.998762845993 +-0.0344226919115 0.999407231808 +-0.0142263034359 0.999898433685 +0.010806764476 0.99994134903 +0.0412350520492 0.999149262905 +0.0792614966631 0.996853649616 +0.129020795226 0.991641521454 +0.195433184505 0.980717003345 +0.281756281853 0.959485650063 +0.386924922466 0.922111213207 +0.504278898239 0.863540768623 +0.622863888741 0.782330095768 +0.731002867222 0.682374298573 +0.823055267334 0.567960977554 +0.888858795166 0.458180963993 +0.934158444405 0.356857925653 +0.96304744482 0.26933068037 +0.980264902115 0.197687223554 +0.990035533905 0.14081607759 +0.998876273632 0.047392744571 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999943315983 0.0106474440545 +0.999882161617 0.0153526319191 +0.999762535095 0.0217908900231 +0.999536454678 0.0304439291358 +0.999097287655 0.0424786098301 +0.997448086739 0.0713941603899 +0.987143814564 0.159833043814 +0.973357260227 0.229292675853 +0.952606976032 0.304203212261 +0.919394433498 0.393336623907 +0.869457900524 0.494006872177 +0.799487173557 0.600682973862 +0.708841025829 0.705368101597 +0.601017415524 0.79923582077 +0.483811587095 0.875171780586 +0.367556542158 0.930000901222 +0.262059777975 0.965051591396 +0.173831284046 0.984775185585 +0.104953631759 0.994476914406 +0.0537867061794 0.998552203178 +0.0167000330985 0.999860465527 +-0.010198155418 0.999947726727 +-0.0299957916141 0.999549746513 +-0.0447006225586 0.999000072479 +-0.0554890856147 0.998459219933 +-0.0631073713303 0.998006641865 +-0.0681715831161 0.997673511505 +-0.0712880790234 0.997455775738 +-0.0730365365744 0.997329235077 +-0.0738956257701 0.997265934944 +-0.0741742029786 0.997245073318 +-0.073970630765 0.997260093689 +-0.0731405764818 0.997321426868 +-0.0712607800961 0.997457623482 +-0.0676052048802 0.997711896896 +-0.061204329133 0.998125076294 +-0.0510335713625 0.998696923256 +-0.036251373589 0.999342441559 +-0.0162514969707 0.999867737293 +0.00969900377095 0.999952852726 +0.043168220669 0.999067723751 +0.0871132910252 0.996198296547 +0.145590737462 0.989344835281 +0.222273364663 0.974984407425 +0.318179637194 0.948030292988 +0.429746299982 0.902949690819 +0.548594355583 0.836088359356 +0.66363120079 0.748059809208 +0.764623582363 0.644477069378 +0.847655117512 0.530546963215 +0.905634284019 0.424059420824 +0.944725573063 0.327861398458 +0.969255387783 0.246055260301 +0.98369550705 0.17984123528 +0.991797983646 0.127814099193 +0.999173939228 0.0406366661191 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999959111214 0.00903437845409 +0.999915122986 0.0130283329636 +0.999828934669 0.0184947475791 +0.999665975571 0.0258441511542 +0.999351739883 0.0360014736652 +0.998016476631 0.0629530549049 +0.989610314369 0.143775612116 +0.978436052799 0.206548258662 +0.961278378963 0.275578141212 +0.933398604393 0.35884091258 +0.890686154366 0.454618185759 +0.829438924789 0.558596730232 +0.747845709324 0.663872241974 +0.647541165352 0.762030243874 +0.53433328867 0.845273792744 +0.417302012444 0.9087677598 +0.306358873844 0.951915979385 +0.209421947598 0.977825284004 +0.130629703403 0.991431057453 +0.0702386498451 0.997530043125 +0.0258173048496 0.999666452408 +-0.0061486531049 0.9999807477 +-0.0289902705699 0.999579548836 +-0.0452467873693 0.99897557497 +-0.0566366910934 0.998394608498 +-0.0643228963017 0.997928977013 +-0.0691967830062 0.997602820396 +-0.0720354989171 0.997401833534 +-0.0735224336386 0.997293293476 +-0.0741948932409 0.997243463993 +-0.0743866115808 0.997229158878 +-0.0741940885782 0.997243642807 +-0.0734532698989 0.997298419476 +-0.0717182531953 0.99742436409 +-0.0682522058487 0.997667968273 +-0.0620815493166 0.998070895672 +-0.052126776427 0.998640358448 +-0.0373182296753 0.999303221703 +-0.0165259111673 0.999863445759 +0.0117867421359 0.999930202961 +0.0500036366284 0.998748838902 +0.101429708302 0.994842350483 +0.169542312622 0.985522687435 +0.256369233131 0.966578781605 +0.360586822033 0.932725667953 +0.476430565119 0.879211902618 +0.5944262743 0.804149806499 +0.704005181789 0.710194647312 +0.796757698059 0.6042984128 +0.870535194874 0.492105931044 +0.920891225338 0.389819055796 +0.954171895981 0.299258232117 +0.974733352661 0.223371237516 +0.986692965031 0.162592917681 +0.99333178997 0.115287907422 +0.999410510063 0.0343288965523 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999971389771 0.00756241939962 +0.99994045496 0.0109067335725 +0.999880075455 0.0154849439859 +0.999765813351 0.0216418690979 +0.999546766281 0.0301033686846 +0.998474538326 0.0552128478885 +0.991688489914 0.128660067916 +0.98273563385 0.185013532639 +0.968709468842 0.248197004199 +0.945584654808 0.325375497341 +0.909516990185 0.415666490793 +0.856646537781 0.515903353691 +0.784310281277 0.620368599892 +0.692536950111 0.721381962299 +0.585140287876 0.810931861401 +0.469571858644 0.882894098759 +0.355230867863 0.934778392315 +0.25088429451 0.968017041683 +0.162471473217 0.986713111401 +0.0922487527132 0.995735883713 +0.0393282212317 0.999226093292 +0.000980124692433 0.999999344349 +-0.0260538198054 0.999660551548 +-0.0446945242584 0.999000668526 +-0.0572033748031 0.99836230278 +-0.06524091959 0.997869491577 +-0.0700653865933 0.997542262077 +-0.0726910233498 0.997354388237 +-0.0739437863231 0.997262239456 +-0.0744423493743 0.997225344181 +-0.0745595172048 0.997216165066 +-0.0743962302804 0.997228682041 +-0.0737635716796 0.997275471687 +-0.072171792388 0.997392117977 +-0.0688292607665 0.997628450394 +-0.062681183219 0.998033463955 +-0.0524771399796 0.998621821404 +-0.0367899499834 0.999322831631 +-0.0138959772885 0.999903321266 +0.0184577461332 0.999829411507 +0.0631690397859 0.998002767563 +0.123422019184 0.992354035378 +0.201631888747 0.979461252689 +0.297885626554 0.954601585865 +0.408581614494 0.912721633911 +0.526225209236 0.85034507513 +0.640953540802 0.767579436302 +0.743331313133 0.668923199177 +0.827007830143 0.562189996243 +0.891488671303 0.453042238951 +0.934566557407 0.35578763485 +0.962499439716 0.271282970905 +0.979501366615 0.201436519623 +0.989277541637 0.146046295762 +0.994648873806 0.103311538696 +0.999591767788 0.0285695251077 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999980509281 0.00624356744811 +0.999959468842 0.00900537893176 +0.999918222427 0.0127867851406 +0.999840259552 0.017873249948 +0.999691724777 0.0248286984861 +0.998837351799 0.0482060499489 +0.993377387524 0.11489558965 +0.986243128777 0.165300115943 +0.974837362766 0.222916319966 +0.955773353577 0.294103831053 +0.925536096096 0.378658652306 +0.880296766758 0.474423021078 +0.816853582859 0.576844990253 +0.733974575996 0.679176867008 +0.633661329746 0.773610472679 +0.521580457687 0.853201746941 +0.406121462584 0.913818895817 +0.296282172203 0.955100357533 +0.199352905154 0.979927539825 +0.119466006756 0.992838263512 +0.0574548952281 0.998347759247 +0.0117132822052 0.999931156635 +-0.02059962973 0.999787628651 +-0.0425474978983 0.999094188213 +-0.0568372830749 0.998383283615 +-0.0656411796808 0.99784308672 +-0.0706502795219 0.997501015663 +-0.0731854736805 0.997318208218 +-0.0742665156722 0.997238278389 +-0.0746245458722 0.997211456299 +-0.0746870115399 0.997206747532 +-0.0745620056987 0.99721622467 +-0.0740257203579 0.997256219387 +-0.072516143322 0.997367024422 +-0.0691337585449 0.99760723114 +-0.0626567006111 0.998034954071 +-0.0515559911728 0.998670041561 +-0.0339642055333 0.999422907829 +-0.0075878216885 0.999970972538 +0.0303398836404 0.99953943491 +0.0828477665782 0.996562063694 +0.152537032962 0.988297522068 +0.240396544337 0.97067463398 +0.344494104385 0.938788414001 +0.45926579833 0.888298630714 +0.576131820679 0.817356705666 +0.685541450977 0.728033423424 +0.779614210129 0.626259803772 +0.854053199291 0.520185053349 +0.909750580788 0.415154606104 +0.946251988411 0.323429882526 +0.969507098198 0.245061933994 +0.983467519283 0.181083574891 +0.991408705711 0.130799755454 +0.995729804039 0.0923113897443 +0.99972563982 0.0234217606485 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999987065792 0.00508302962407 +0.999973118305 0.00733196735382 +0.999945819378 0.0104115484282 +0.999894082546 0.0145546700805 +0.999795973301 0.0201950855553 +0.99911659956 0.0420223996043 +0.994751513004 0.102319724858 +0.989103555679 0.147221088409 +0.979892253876 0.199526116252 +0.964296281338 0.264824837446 +0.939169704914 0.343452721834 +0.900854706764 0.43412014842 +0.845874428749 0.533381700516 +0.772066295147 0.635541915894 +0.679862737656 0.733339071274 +0.573114931583 0.819474935532 +0.458822757006 0.888527810574 +0.345625311136 0.93837249279 +0.241627141833 0.970368981361 +0.152587890625 0.988289833069 +0.0811272934079 0.996703505516 +0.0270453877747 0.99963414669 +-0.0117283919826 0.999931156635 +-0.0381036587059 0.999273478985 +-0.0550606399775 0.998482763767 +-0.065238058567 0.997869491577 +-0.0708002150059 0.997490406036 +-0.0734480023384 0.997299015522 +-0.0744627714157 0.997223675251 +-0.0747336447239 0.997203350067 +-0.0747644975781 0.997201025486 +-0.0746722817421 0.997208058834 +-0.0741808190942 0.997244656086 +-0.0726152434945 0.997359991074 +-0.0688984394073 0.997623562813 +-0.0615437366068 0.998104274273 +-0.04864513129 0.998815834522 +-0.0278580281883 0.999611735344 +0.00358004961163 0.999993443489 +0.0486687645316 0.998814761639 +0.110144883394 0.993915438652 +0.189586400986 0.98186391592 +0.286278396845 0.958146214485 +0.396319448948 0.918112576008 +0.512622475624 0.858613967896 +0.626204848289 0.779658436775 +0.728448927402 0.685099720955 +0.813311636448 0.581827938557 +0.87844234705 0.477847993374 +0.925839781761 0.377915889025 +0.956356167793 0.292203426361 +0.975478947163 0.220091983676 +0.986809432507 0.161885097623 +0.993188858032 0.116514615715 +0.996628940105 0.0820382237434 +0.999820947647 0.0189141631126 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999991595745 0.0040798871778 +0.999982655048 0.00588530302048 +0.999965071678 0.0083577958867 +0.999931752682 0.0116845816374 +0.999868750572 0.016196006909 +0.999324083328 0.0367597825825 +0.995826482773 0.0912650823593 +0.991345465183 0.13127656281 +0.983892679214 0.178759142756 +0.971121251583 0.238585084677 +0.950248837471 0.311490565538 +0.917868733406 0.396883487701 +0.870435774326 0.492281466722 +0.805182278156 0.59302675724 +0.721315145493 0.692606568336 +0.621045589447 0.783774256706 +0.509843349457 0.860267102718 +0.395537227392 0.918449878693 +0.286491185427 0.958082675934 +0.189643219113 0.981853067875 +0.109233334661 0.994016110897 +0.0465691797435 0.998914957047 +0.000611132767517 0.999999582767 +-0.0311001241207 0.999516129494 +-0.0515809357166 0.998668670654 +-0.0638042837381 0.997962355614 +-0.0703765302896 0.997520387173 +-0.0734121575952 0.997301578522 +-0.074510447681 0.997219979763 +-0.0747669637203 0.997201025486 +-0.0747883394361 0.997199237347 +-0.0747017040849 0.997205734253 +-0.0741540193558 0.997246682644 +-0.072308011353 0.997382342815 +-0.0678383633494 0.997696280479 +-0.0589189007878 0.998262643814 +-0.0432309433818 0.999065101147 +-0.0180156007409 0.999837577343 +0.0197524726391 0.99980455637 +0.0729656293988 0.997334301472 +0.143678620458 0.989624261856 +0.232152268291 0.972679197788 +0.335929512978 0.941887140274 +0.449455946684 0.893302381039 +0.564730703831 0.825275242329 +0.673030912876 0.739614129066 +0.767083585262 0.641546785831 +0.842692136765 0.538395404816 +0.899148106575 0.437643975019 +0.939211845398 0.343337804079 +0.96461379528 0.263666212559 +0.980296075344 0.197533339262 +0.989478051662 0.144681319594 +0.994599401951 0.103786535561 +0.997338354588 0.0729114934802 +0.99988669157 0.015044872649 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999994814396 0.00322801130824 +0.99998909235 0.00465665198863 +0.999978125095 0.00661330670118 +0.99995726347 0.00924627762288 +0.999918997288 0.0127266831696 +0.999479293823 0.0322654359043 +0.996683835983 0.0813675373793 +0.99313390255 0.116980947554 +0.987116456032 0.160001769662 +0.976689636707 0.214655190706 +0.959423065186 0.281969815493 +0.932211756706 0.361912667751 +0.891593158245 0.452836841345 +0.834451556206 0.551080584526 +0.759069979191 0.65100890398 +0.666226506233 0.745749056339 +0.559818923473 0.828614652157 +0.446526914835 0.894770145416 +0.334453701973 0.942411899567 +0.231255665421 0.972892820835 +0.14255002141 0.989787518978 +0.0711699724197 0.997464120388 +0.0173153318465 0.999849915504 +-0.020736252889 0.999784767628 +-0.0457725785673 0.998951733112 +-0.0609198845923 0.998142421246 +-0.0691474750638 0.997606039047 +-0.0729873478413 0.997332751751 +-0.0744048282504 0.997227787971 +-0.0747560933232 0.997201800346 +-0.0747843384743 0.997199475765 +-0.0746279507875 0.99721121788 +-0.0738236680627 0.997270941734 +-0.0713116005063 0.997453868389 +-0.0654469504952 0.997855901718 +-0.0540132373571 0.998540043831 +-0.0342983528972 0.999411582947 +-0.00326398899779 0.999994456768 +0.0421115010977 0.999112606049 +0.10425452888 0.994550406933 +0.184188082814 0.982890963554 +0.280656754971 0.959808170795 +0.389548689127 0.921005725861 +0.504071891308 0.863661646843 +0.615931093693 0.787799715996 +0.717228472233 0.69683778286 +0.802295207977 0.596927165985 +0.868684887886 0.495364636183 +0.917020857334 0.398838669062 +0.950536906719 0.310611248016 +0.971497654915 0.237048581243 +0.984261751175 0.176715984941 +0.991653740406 0.128928631544 +0.995740413666 0.0921978875995 +0.997904419899 0.0647005885839 +0.99993032217 0.0117871798575 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999997138977 0.00240057753399 +0.999993979931 0.00346364593133 +0.999987900257 0.00491999322549 +0.999976336956 0.00688032899052 +0.999955117702 0.0094725433737 +0.999604165554 0.0281330570579 +0.997401595116 0.0720415189862 +0.994617581367 0.103611633182 +0.989807426929 0.142411649227 +0.981374025345 0.192105799913 +0.967220127583 0.25393858552 +0.944563686848 0.328327834606 +0.910120010376 0.414344727993 +0.860617041588 0.509252309799 +0.793673992157 0.608343064785 +0.708869099617 0.7053399086 +0.608591198921 0.79348385334 +0.498174846172 0.867076396942 +0.385048896074 0.92289608717 +0.27712392807 0.960834145546 +0.1810695678 0.983470082283 +0.101151004434 0.994871079922 +0.0389226078987 0.999242186546 +-0.00636590830982 0.999979615211 +-0.0370135940611 0.99931460619 +-0.0560860224068 0.998425900936 +-0.0667837932706 0.997767329216 +-0.0720088109374 0.997403919697 +-0.0741041526198 0.997250378132 +-0.074721083045 0.997204363346 +-0.0747653022408 0.997201085091 +-0.0743848085403 0.997229576111 +-0.0729741454124 0.997333645821 +-0.0692034289241 0.997602462769 +-0.0610715039074 0.99813336134 +-0.0459806099534 0.998942136765 +-0.0209229234606 0.999780833721 +0.0172114614397 0.999851584435 +0.0711385458708 0.99746632576 +0.142487809062 0.989796340466 +0.231000706553 0.972953438759 +0.333867102861 0.942619979382 +0.445579797029 0.895242035389 +0.558629870415 0.829417049885 +0.665017902851 0.746827423573 +0.758071064949 0.652171611786 +0.833807051182 0.552055776119 +0.891324877739 0.453364849091 +0.932244420052 0.361828625202 +0.960005581379 0.279980152845 +0.977172017097 0.212448447943 +0.987494409084 0.157653510571 +0.99341160059 0.114600196481 +0.996656179428 0.0817082375288 +0.998362600803 0.0571984760463 +0.99995970726 0.00897396076471 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999998271465 0.0018565854989 +0.999996423721 0.00267875404097 +0.999992787838 0.00380508275703 +0.999985814095 0.00532120047137 +0.99997317791 0.00732602085918 +0.999673902988 0.0255354829133 +0.99788069725 0.0650657117367 +0.995623290539 0.09345395118 +0.991658508778 0.128891006112 +0.984649538994 0.174542039633 +0.972771823406 0.231764540076 +0.953539609909 0.301266759634 +0.923900008202 0.382634013891 +0.880601882935 0.47385686636 +0.820912778378 0.57105332613 +0.743591964245 0.668633401394 +0.649824380875 0.76008439064 +0.543662488461 0.839303731918 +0.431610792875 0.902059793472 +0.321357548237 0.946957945824 +0.220112964511 0.975474298 +0.133209183812 0.991087734699 +0.0634149312973 0.997987151146 +0.0110126798972 0.999939203262 +-0.0256218090653 0.999671638012 +-0.0492643229663 0.998785734177 +-0.0631384477019 0.998004734516 +-0.0703638345003 0.997521281242 +-0.073572203517 0.997289717197 +-0.0746689662337 0.997207999229 +-0.0747060105205 0.99720543623 +-0.0738314762712 0.997270584106 +-0.0712912082672 0.997455537319 +-0.0654940530658 0.997852921486 +-0.0541290901601 0.998533964157 +-0.0343223363161 0.999410688877 +-0.00295167486183 0.999995589256 +0.0429185517132 0.999078452587 +0.105433531106 0.994426250458 +0.185220927 0.982696890831 +0.280697286129 0.959796369076 +0.387699306011 0.921785891056 +0.499770790339 0.866157412529 +0.609245955944 0.79298132658 +0.708873033524 0.705335855484 +0.793367683887 0.608742535114 +0.860273718834 0.509832262993 +0.909890472889 0.414847820997 +0.944486320019 0.328550547361 +0.967525184155 0.25277364254 +0.981621801853 0.190836325288 +0.990004003048 0.141038998961 +0.994765460491 0.102183170617 +0.997356951237 0.0726552903652 +0.998711585999 0.0507431030273 +0.999976634979 0.00683066807687 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999998986721 0.00141360494308 +0.999997913837 0.00203960435465 +0.999995827675 0.00289719458669 +0.999991774559 0.00405156938359 +0.999984443188 0.00557805737481 +0.999723315239 0.023518987 +0.998254358768 0.0590599291027 +0.996405422688 0.0847116559744 +0.993109941483 0.117185853422 +0.987241923809 0.159226506948 +0.977214634418 0.212252914906 +0.960818171501 0.277178883553 +0.935249745846 0.353988051414 +0.897370994091 0.44127625227 +0.844275355339 0.535909175873 +0.774141788483 0.633011996746 +0.687170147896 0.72649627924 +0.586218297482 0.810152947903 +0.476742982864 0.879042685032 +0.365898728371 0.930654585361 +0.261056363583 0.965323328972 +0.168308213353 0.985734403133 +0.0914895609021 0.995805978775 +0.031932476908 0.999489843845 +-0.0111794127151 0.999937355518 +-0.040143404156 0.999193787575 +-0.0580134540796 0.998315691948 +-0.067965015769 0.997687637806 +-0.0728025361896 0.99734634161 +-0.0746146887541 0.997212350368 +-0.0745634511113 0.997216165066 +-0.0727871134877 0.997347354889 +-0.0683981850743 0.997658014297 +-0.0595937147737 0.998222529888 +-0.043851274997 0.999037802219 +-0.0181756205857 0.999834775925 +0.020459074527 0.999790489674 +0.07457164675 0.997215628624 +0.145512357354 0.989356458187 +0.232777744532 0.972529768944 +0.333508968353 0.94274687767 +0.442464292049 0.896785914898 +0.552691578865 0.833385765553 +0.656845092773 0.75402545929 +0.748733401299 0.662870883942 +0.824501514435 0.565859675407 +0.883025765419 0.469323992729 +0.925509870052 0.378723233938 +0.954603850842 0.297878056765 +0.973658323288 0.228011593223 +0.985208809376 0.171357467771 +0.992008209229 0.126172974706 +0.99583864212 0.0911328867078 +0.997909128666 0.0646315440536 +0.998984932899 0.0450394004583 +0.999986827374 0.00511999009177 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999463558 0.00105963263195 +0.999998807907 0.00152888079174 +0.999997615814 0.00217172666453 +0.999995410442 0.00303704664111 +0.999991238117 0.00418129796162 +0.999758183956 0.0219888743013 +0.998545348644 0.0539172776043 +0.997012257576 0.0772411674261 +0.994244039059 0.107137039304 +0.98928463459 0.145998224616 +0.980750083923 0.195265844464 +0.966679811478 0.255988061428 +0.94452136755 0.328449726105 +0.911301314831 0.411739677191 +0.864068508148 0.503373920918 +0.80062186718 0.599169671535 +0.720395803452 0.693562805653 +0.625198483467 0.780465722084 +0.51942139864 0.854518055916 +0.409481048584 0.912318468094 +0.302585154772 0.953122079372 +0.205265939236 0.97870606184 +0.122213326395 0.992503881454 +0.0557448938489 0.998444855213 +0.00591752352193 0.999982237816 +-0.0289391204715 0.999581038952 +-0.0515247732401 0.998671531677 +-0.0648880600929 0.997892379761 +-0.0718520060182 0.997415065765 +-0.0745783001184 0.997215032578 +-0.0742788612843 0.997237443924 +-0.0710739418864 0.997470915318 +-0.0639882162213 0.997950434685 +-0.051105696708 0.998693048954 +-0.0298453085124 0.999554276466 +0.00271035986952 0.999996304512 +0.0492667108774 0.998785495758 +0.111710183322 0.993740618229 +0.190445274115 0.981697678566 +0.283819764853 0.958877384663 +0.387871712446 0.921713173389 +0.49664029479 0.867956459522 +0.603125929832 0.797645509243 +0.700678706169 0.713476598263 +0.784328103065 0.620345950127 +0.851564347744 0.524249613285 +0.90235298872 0.430997163057 +0.938524663448 0.345211803913 +0.962901592255 0.26985219121 +0.978630006313 0.205628484488 +0.988086283207 0.153900489211 +0.993602275848 0.112935394049 +0.99668610096 0.0813406333327 +0.998342454433 0.057547558099 +0.999198794365 0.0400182530284 +0.999992728233 0.00377922574989 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999701977 0.000781981623732 +0.999999344349 0.00112827436533 +0.999998688698 0.00160267937463 +0.999997496605 0.00224126433022 +0.999995231628 0.0030856942758 +0.99978607893 0.0206793211401 +0.998784959316 0.0492789596319 +0.997515559196 0.0704443901777 +0.995189964771 0.0979621857405 +0.990998148918 0.133874058723 +0.98373478651 0.17962653935 +0.971662998199 0.236369550228 +0.952472627163 0.304624080658 +0.923381209373 0.383884251118 +0.881471216679 0.472237616777 +0.824297428131 0.566156446934 +0.750695884228 0.660647511482 +0.661559998989 0.749891936779 +0.560245871544 0.828326165676 +0.452313959599 0.891858637333 +0.344574272633 0.938758909702 +0.243733748794 0.969842135906 +0.155135676265 0.987893044949 +0.0819988250732 0.996632218361 +0.02528478764 0.999680101871 +-0.015941850841 0.999872684479 +-0.043882932514 0.999036550522 +-0.0612788163126 0.998120605946 +-0.070806093514 0.997490048409 +-0.0745751783252 0.997215330601 +-0.0737802833319 0.997274518013 +-0.0685207471251 0.997649550438 +-0.0577972345054 0.998328328133 +-0.0397041290998 0.999211490154 +-0.0117763485759 0.999930560589 +0.0286146700382 0.999590277672 +0.0836360454559 0.996496200562 +0.154354840517 0.98801535368 +0.240128800273 0.97074085474 +0.338202297688 0.941073298454 +0.443733841181 0.896158516407 +0.550408601761 0.834895312786 +0.651570796967 0.75858771801 +0.741538167 0.670910477638 +0.816628992558 0.577162742615 +0.875555753708 0.483117043972 +0.919148802757 0.393909692764 +0.949648559093 0.313316583633 +0.969897508621 0.243512302637 +0.982781946659 0.18476806581 +0.990467488766 0.137745946646 +0.994911730289 0.100749947131 +0.997378051281 0.0723622366786 +0.998694837093 0.0510717220604 +0.999371767044 0.0354387424886 +0.999996542931 0.00262605235912 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999821186 0.000568136107177 +0.999999642372 0.000819729466457 +0.999999344349 0.00116440095007 +0.999998688698 0.00162835291121 +0.999997496605 0.00224186177365 +0.999810397625 0.0194706972688 +0.998988211155 0.0449700430036 +0.997932314873 0.0642716363072 +0.995979487896 0.0895790532231 +0.992441236973 0.122719421983 +0.986273288727 0.165120646358 +0.975950062275 0.217993065715 +0.95940220356 0.28203997016 +0.93406689167 0.357097536325 +0.897131383419 0.44176363945 +0.84602701664 0.533139824867 +0.779139339924 0.626850545406 +0.696572780609 0.717485964298 +0.600679695606 0.799489319324 +0.496058404446 0.868288934231 +0.388887047768 0.921285271645 +0.285761982203 0.958300471306 +0.192442163825 0.981308281422 +0.112925171852 0.993603348732 +0.049088306725 0.99879437685 +0.000864145520609 0.999999523163 +-0.033235900104 0.999447286129 +-0.0554615259171 0.998460710049 +-0.0681780874729 0.997672975063 +-0.0733242854476 0.997307777405 +-0.0720236003399 0.997402787209 +-0.0643812939525 0.997925400734 +-0.0494787655771 0.998774945736 +-0.0255857612938 0.999672532082 +0.00944841466844 0.999955236912 +0.0577600486577 0.998330235481 +0.120815463364 0.992674946785 +0.198785066605 0.980042934418 +0.290031731129 0.957016944885 +0.390883743763 0.920440018177 +0.495967626572 0.868340790272 +0.599008858204 0.800742149353 +0.693991541862 0.719982743263 +0.776295781136 0.63036864996 +0.843406736851 0.537275254726 +0.895003497601 0.446058869362 +0.932505846024 0.361154198647 +0.958353877068 0.28558331728 +0.9752997756 0.220884740353 +0.985955715179 0.167005375028 +0.992271006107 0.124088615179 +0.995895802975 0.0905053988099 +0.99789506197 0.0648470744491 +0.998956561089 0.0456704609096 +0.999499619007 0.0316303372383 +0.999998211861 0.00188517640345 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 diff --git a/examples/core/globalNavSwap/fieldM.txt b/examples/core/globalNavSwap/fieldM.txt new file mode 100644 index 00000000..970b48f4 --- /dev/null +++ b/examples/core/globalNavSwap/fieldM.txt @@ -0,0 +1,171 @@ +14 12 +1.5 +-8.50642590769 -5.29629363242 +-0.0112293837592 0.999936282635 +-0.0435877367854 0.999048888683 +-0.0452105402946 0.99897646904 +-0.0415199138224 0.999136567116 +-0.0253759399056 0.999675571918 +-0.0393449142575 0.999223172665 +-0.027881398797 0.99960899353 +-0.0381889604032 0.99926918745 +-0.0453705564141 0.998969137669 +-0.0457011125982 0.998954176903 +-0.0438264459372 0.999038279057 +0.00522626843303 0.999985575676 +-0.0358351767063 0.999356627464 +-0.0463883057237 0.998922765255 +-0.0473756156862 0.99887573719 +-0.0385443940759 0.999255299568 +-0.036030754447 0.999347746372 +-0.00965140759945 0.999949574471 +-0.0312357544899 0.999509096146 +-0.0339441411197 0.999421656132 +-0.0483640469611 0.998828470707 +-0.0474058203399 0.998874247074 +-0.046498298645 0.998917043209 +-0.030027706176 0.9995470047 +-0.0441814400256 0.999022424221 +-0.047933023423 0.99884980917 +-0.0482999272645 0.998831748962 +-0.0414081439376 0.999140679836 +-0.085833966732 0.996306598186 +-0.176093548536 0.984367370605 +0.0685166046023 0.997646391392 +-0.0367183126509 0.999322533607 +-0.0485928356647 0.998817563057 +-0.0487760752439 0.99880862236 +-0.0480272509158 0.998844742775 +-0.0414110273123 0.999140977859 +-0.0474451631308 0.998872935772 +-0.0491158887744 0.998791515827 +-0.0497354716063 0.998760163784 +-0.0488882064819 0.998801112175 +-0.0792580768466 0.9968495965 +-0.0183943342417 0.999824464321 +0.546867787838 0.837214648724 +0.0287297852337 0.999582767487 +-0.049536023289 0.998770952225 +-0.0491542182863 0.998789846897 +-0.0489444211125 0.998800098896 +-0.0456585213542 0.998955786228 +-0.0506924204528 0.998713254929 +-0.0538362637162 0.998547911644 +-0.0578368455172 0.99832367897 +-0.0870278254151 0.996201395988 +-0.607985854149 0.793940067291 +-0.986400187016 0.164325416088 +0.0959795191884 0.995379507542 +-0.348858684301 0.937170267105 +-0.954512357712 0.298165082932 +-0.0539722517133 0.998540818691 +-0.0511976145208 0.998687267303 +-0.0481913536787 0.998836696148 +-0.0564411506057 0.998404443264 +-0.0625293776393 0.998040378094 +-0.378283172846 0.925685882568 +-0.0802260860801 0.996773421764 +-0.881970703602 0.471288263798 +-0.612352907658 0.790574908257 +-0.14513169229 0.989405691624 +0.605133891106 0.796117961407 +-0.0696145072579 0.997571885586 +-0.06362118572 0.997971713543 +-0.0572322309017 0.998359501362 +-0.0517049506307 0.99866104126 +-0.0631945133209 0.997999787331 +-0.0687729716301 0.997631251812 +-0.388502180576 0.921444892883 +0.413884520531 0.910324752331 +0.44821035862 0.893919706345 +-0.608470976353 0.79356688261 +-0.436982005835 0.89946103096 +0.394825339317 0.918749153614 +0.401607453823 0.915808081627 +-0.0708827450871 0.997482419014 +-0.0649957060814 0.99788403511 +-0.0572474971414 0.998358547688 +-0.0655554458499 0.997847557068 +-0.0658092498779 0.997830271721 +0.997409284115 -0.0718883275986 +0.995723545551 -0.0923268422484 +-0.0139148216695 0.999898672104 +-0.849315166473 -0.527876377106 +0.494277894497 0.869295656681 +-0.386676549911 0.922207772732 +-0.979757666588 -0.200167298317 +-0.0690308660269 0.997609972954 +-0.0686054378748 0.997642040253 +-0.0625818669796 0.998038470745 +-0.059720993042 0.998214006424 +0.974676549435 0.223604679108 +0.971339285374 0.237684711814 +0.918667256832 0.395020753145 +0.659869074821 0.751373291016 +0.236921787262 0.971523702145 +-0.516217768192 0.856449484825 +-0.154910817742 0.987923145294 +-0.864135563374 0.503250718117 +-0.961292266846 0.275519549847 +-0.0643311142921 0.99792689085 +-0.0640164464712 0.997947514057 +-0.0470764525235 0.998890161514 +0.928247988224 -0.371957033873 +0.909905612469 -0.414810836315 +0.992792367935 -0.119825206697 +0.376177608967 0.9265422225 +0.228799089789 0.973465383053 +-0.086031332612 0.996286869049 +-0.972785949707 0.231688931584 +-0.885049104691 -0.465493798256 +-0.997719824314 -0.0674635767937 +-0.995133519173 -0.0985127538443 +-0.0595521964133 0.998224020004 +-0.0317495279014 0.99949491024 +-0.0197206083685 0.999804377556 +-0.0114989429712 0.999932706356 +-0.00692329881713 0.999975025654 +-0.000498694193084 0.999995946884 +0.0249492675066 0.999682605267 +0.0504561774433 0.99871981144 +-0.00837675761431 0.999960362911 +-0.0147537225857 0.999889433384 +-0.0248835198581 0.999689102173 +-0.0384750701487 0.9992582798 +-0.0501241087914 0.998741567135 +-0.0183417871594 0.999831140041 +-0.00840245746076 0.99996393919 +-0.00333808688447 0.999993443489 +-0.0013236226514 0.999998211861 +-0.000668327906169 0.999995350838 +0.199521437287 0.979889392853 +0.193418726325 0.981112003326 +-0.00198467611335 0.999995112419 +-0.00514127314091 0.999985635281 +-0.0122863370925 0.999923586845 +-0.0247292667627 0.999692499638 +-0.0383283421397 0.999264478683 +-0.00929295178503 0.999956130981 +-0.00279341125861 0.999995231628 +-0.000611859606579 0.999998629093 +-0.000116095296107 0.99999910593 +-3.02036296489e-05 0.999998927116 +7.82339338912e-06 0.999998748302 +-5.05883908772e-05 0.999998807907 +-0.000245447969064 0.999998867512 +-0.00126037164591 0.999998152256 +-0.00504085142165 0.999986410141 +-0.0144060133025 0.999895215034 +-0.0265705753118 0.999645709991 +-0.00443650502712 0.999989509583 +-0.00079857459059 0.999998986721 +-7.67658420955e-05 0.999999046326 +-4.22036191594e-06 0.99999910593 +-2.50142818459e-07 0.999999284744 +-7.63088152667e-08 0.999998867512 +-8.56178360209e-07 0.999998688698 +-1.65348683367e-05 0.99999922514 +-0.000239846020122 0.99999910593 +-0.00187579181511 0.999996840954 +-0.00805417168885 0.999966740608 +-0.0159477815032 0.999871969223 diff --git a/examples/core/globalNavSwap/globalNavSwapBFieldM.xml b/examples/core/globalNavSwap/globalNavSwapBFieldM.xml new file mode 100644 index 00000000..7dc48a05 --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapBFieldM.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/globalNavSwap/globalNavSwapBMap.xml b/examples/core/globalNavSwap/globalNavSwapBMap.xml new file mode 100644 index 00000000..efdddc2d --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapBMap.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/core/globalNavSwap/globalNavSwapBMesh.xml b/examples/core/globalNavSwap/globalNavSwapBMesh.xml new file mode 100644 index 00000000..062dfc4e --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapBMesh.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/globalNavSwap/globalNavSwapCut.mtl b/examples/core/globalNavSwap/globalNavSwapCut.mtl new file mode 100644 index 00000000..c89145d9 --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapCut.mtl @@ -0,0 +1,6 @@ +newmtl initialShadingGroup +illum 4 +Kd 0.50 0.50 0.50 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +Ni 1.00 diff --git a/examples/core/globalNavSwap/globalNavSwapS.xml b/examples/core/globalNavSwap/globalNavSwapS.xml new file mode 100644 index 00000000..2912946c --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapS.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/globalNavSwap/globalNavSwapV.xml b/examples/core/globalNavSwap/globalNavSwapV.xml new file mode 100644 index 00000000..ce9ff5ce --- /dev/null +++ b/examples/core/globalNavSwap/globalNavSwapV.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/core/globalNavSwap/graph.txt b/examples/core/globalNavSwap/graph.txt new file mode 100644 index 00000000..af597b2e --- /dev/null +++ b/examples/core/globalNavSwap/graph.txt @@ -0,0 +1,97 @@ +39 +2 -0.955341 -2.947240 +2 0.707544 -2.984588 +3 2.020475 0.957439 +2 6.070931 1.003467 +3 -2.029982 0.934425 +2 -5.988383 0.957439 +3 6.070931 3.488974 +3 5.886820 5.468175 +2 5.771750 7.930385 +3 -5.942355 3.511988 +3 -6.011397 5.399133 +2 -6.057425 8.045738 +3 -1.818319 7.907637 +3 1.952303 7.953098 +4 0.161432 8.039763 +2 0.868311 10.610772 +2 -0.568460 10.632591 +2 2.066503 6.618873 +2 -1.983670 6.607508 +3 -1.914912 5.606259 +3 -3.157666 5.491189 +3 -2.904513 3.488974 +3 -2.029982 2.890612 +3 -1.086410 3.419933 +2 -0.971340 4.478575 +3 -0.971340 5.422147 +3 2.043489 5.491189 +3 2.895005 5.422147 +3 1.007860 5.422147 +2 0.984846 4.501589 +4 1.007860 3.465961 +2 3.033089 4.455561 +4 3.056103 3.511988 +3 2.043489 2.606303 +2 0.135748 12.783532 +4 -0.926313 -1.250922 +4 -0.703009 0.515211 +4 1.103725 0.535512 +4 0.819520 -1.169721 +55 +4 5 +2 3 +8 13 +7 8 +6 7 +3 6 +5 9 +9 10 +10 11 +11 12 +14 13 +12 14 +15 14 +16 14 +17 13 +18 12 +19 18 +20 19 +20 10 +21 20 +9 21 +22 21 +23 22 +24 23 +25 19 +27 7 +27 26 +26 17 +28 26 +28 25 +25 24 +29 28 +30 29 +23 30 +31 27 +32 31 +30 32 +32 6 +33 30 +33 32 +33 2 +22 4 +34 16 +34 15 +36 4 +37 2 +37 36 +38 37 +1 38 +0 35 +0 38 +1 35 +35 37 +38 36 +35 36 + diff --git a/examples/core/globalNavSwap/navmesh.nav b/examples/core/globalNavSwap/navmesh.nav new file mode 100644 index 00000000..dfaa4a2c --- /dev/null +++ b/examples/core/globalNavSwap/navmesh.nav @@ -0,0 +1,528 @@ +68 + -2.00000 -4.00000 + -2.00000 0.00000 + -7.00000 0.00000 + -7.00000 9.00000 + -2.00000 9.00000 + -2.00000 13.00000 + 2.00000 13.00000 + 2.00000 9.00000 + 7.00000 9.00000 + 7.00000 0.00000 + 2.00000 0.00000 + 2.00000 -4.00000 + -1.00000 2.00000 + 1.00000 2.00000 + 1.00000 3.00000 + -1.00000 3.00000 + -5.00000 2.00000 + -3.00000 2.00000 + -3.00000 3.00000 + -5.00000 3.00000 + 3.00000 2.00000 + 5.00000 2.00000 + 5.00000 3.00000 + 3.00000 3.00000 + -2.50000 4.00000 + -1.50000 4.00000 + -1.50000 5.00000 + -2.50000 5.00000 + -4.50000 4.00000 + -3.50000 4.00000 + -3.50000 5.00000 + -4.50000 5.00000 + -0.50000 4.00000 + 0.50000 4.00000 + 0.50000 5.00000 + -0.50000 5.00000 + 1.50000 4.00000 + 2.50000 4.00000 + 2.50000 5.00000 + 1.50000 5.00000 + 3.50000 4.00000 + 4.50000 4.00000 + 4.50000 5.00000 + 3.50000 5.00000 + -1.00000 6.00000 + 1.00000 6.00000 + 1.00000 7.00000 + -1.00000 7.00000 + -5.00000 6.00000 + -3.00000 6.00000 + -3.00000 7.00000 + -5.00000 7.00000 + 3.00000 6.00000 + 5.00000 6.00000 + 5.00000 7.00000 + 3.00000 7.00000 + 0.00000 9.00000 + 0.00000 13.00000 + 0.00000 7.00000 + 0.00000 0.00000 + 0.00000 2.00000 + 0.00000 -4.00000 + -8.87443 29.49450 + 0.00000 29.49450 + 8.87443 29.49450 + -8.87443 46.86641 + 0.00000 46.86641 + 8.87443 46.86641 +68 + 1 17 41 42 + 33 36 16 18 + 5 57 33 50 + 9 21 19 47 + 39 45 25 26 + 22 41 21 22 + 12 17 42 43 + 3 51 30 34 + 13 20 40 46 + 59 61 45 49 + 7 56 36 38 + 10 13 46 48 + 1 59 44 49 + 1 12 42 44 + 14 36 16 17 + 25 32 5 7 + 27 49 11 12 + 43 52 27 28 + 47 50 14 32 + 23 37 17 20 + 8 54 29 37 + 14 33 6 16 + 26 44 12 13 + 57 63 50 51 + 23 40 20 21 + 7 55 35 37 + 19 28 2 3 + 15 25 4 5 + 4 47 32 39 + 63 66 52 53 + 35 44 13 15 + 37 40 20 24 + 10 20 46 47 + 59 60 44 48 + 19 48 1 3 + 15 32 5 6 + 42 53 22 28 + 2 19 0 1 + 14 23 17 40 + 9 22 19 23 + 30 49 10 11 + 22 53 22 23 + 24 29 8 9 + 6 57 38 51 + 27 30 9 11 + 38 43 24 27 + 26 35 7 13 + 4 56 33 39 + 3 48 1 30 + 63 64 51 53 + 34 39 18 25 + 7 46 35 36 + 18 29 2 8 + 56 57 33 38 + 38 52 26 27 + 44 49 12 14 + 15 18 4 43 + 45 52 26 31 + 2 16 0 41 + 18 24 4 8 + 31 48 3 10 + 56 58 36 39 + 62 63 50 52 + 4 50 32 34 + 8 53 23 29 + 34 45 15 25 + 10 59 45 48 + 46 55 31 35 +64 + 55 54 37 50 + 41 40 21 45 + 19 18 2 11 + 0 61 49 40 + 16 19 0 2 + 7 6 38 39 + 45 44 15 15 + 24 27 9 62 + 26 25 7 33 + 29 28 2 55 + 37 36 17 12 + 18 17 43 18 + 36 39 18 32 + 2 1 41 56 + 5 4 33 52 + 44 47 14 54 + 15 14 6 51 + 32 35 7 21 + 17 16 41 4 + 34 33 18 44 + 46 45 31 6 + 35 34 15 19 + 8 7 37 5 + 23 22 21 63 + 9 8 23 22 + 66 65 52 26 + 65 62 52 37 + 21 20 47 61 + 50 49 14 60 + 38 37 24 10 + 51 50 34 28 + 64 67 53 36 + 39 38 26 29 + 25 24 4 7 + 53 52 28 49 + 13 60 48 59 + 67 66 53 25 + 62 5 50 14 + 43 42 28 47 + 6 64 51 31 + 61 11 45 53 + 31 30 10 42 + 30 29 9 9 + 48 51 30 30 + 33 32 6 17 + 40 43 24 38 + 12 15 43 16 + 42 41 22 1 + 3 2 1 13 + 52 55 31 0 + 54 53 29 34 + 14 13 40 35 + 4 3 34 48 + 11 10 45 57 + 47 58 39 58 + 28 31 3 41 + 1 0 49 3 + 10 9 47 24 + 58 46 36 20 + 60 12 44 46 + 49 48 10 43 + 20 23 40 23 + 27 26 12 8 + 22 21 19 27 +defaultGrp +54 + -5.66667 1.66667 + 3 2 16 19 + -0.00000 0.00000 0.00000 + 2 37 58 + 5 13 48 4 18 2 + + -6.00000 4.50000 + 4 2 19 48 3 + 0.00000 0.00000 0.00000 + 3 34 37 48 + 7 13 48 52 2 4 43 60 + + -4.00000 3.50000 + 4 29 28 19 18 + 0.00000 0.00000 0.00000 + 2 26 52 + 6 2 11 4 9 55 42 + + -4.75000 4.50000 + 4 19 28 31 48 + 0.00000 0.00000 0.00000 + 3 26 34 60 + 7 2 4 9 55 41 43 60 + + -2.00000 3.50000 + 4 15 25 24 18 + 0.00000 0.00000 0.00000 + 3 27 56 59 + 7 16 46 2 11 7 33 8 + + -1.00000 3.66667 + 3 15 32 25 + -0.00000 0.00000 0.00000 + 3 15 27 35 + 6 16 46 8 33 17 44 + + 0.00000 3.50000 + 4 32 15 14 33 + 0.00000 0.00000 0.00000 + 2 21 35 + 6 16 51 46 17 44 19 + + -1.00000 4.50000 + 4 25 32 35 26 + 0.00000 0.00000 0.00000 + 2 15 46 + 6 8 33 62 17 44 21 + + -3.00000 3.66667 + 3 18 24 29 + -0.00000 0.00000 0.00000 + 3 42 52 59 + 6 2 11 7 33 9 42 + + -3.00000 4.50000 + 4 29 24 27 30 + 0.00000 0.00000 0.00000 + 2 42 44 + 6 7 33 62 9 42 41 + + -4.00000 5.50000 + 4 48 31 30 49 + 0.00000 0.00000 0.00000 + 2 40 60 + 6 41 42 55 43 60 28 + + -3.00000 5.33333 + 3 49 30 27 + -0.00000 0.00000 0.00000 + 3 16 40 44 + 6 7 62 41 42 28 60 + + -2.00000 5.50000 + 4 27 26 44 49 + 0.00000 0.00000 0.00000 + 3 16 22 55 + 7 8 62 7 6 15 28 60 + + -1.00000 5.33333 + 3 35 44 26 + -0.00000 0.00000 -0.00000 + 3 22 30 46 + 6 8 62 17 21 6 15 + + -2.00000 6.50000 + 4 50 49 44 47 + 0.00000 0.00000 0.00000 + 2 18 55 + 6 6 15 54 28 60 30 + + 0.00000 5.50000 + 4 44 35 34 45 + 0.00000 0.00000 0.00000 + 2 30 65 + 6 19 21 17 6 15 20 + + 1.00000 3.66667 + 3 33 14 36 + 0.00000 0.00000 0.00000 + 3 1 14 21 + 6 16 51 19 44 10 12 + + 2.00000 3.50000 + 4 37 36 14 23 + 0.00000 0.00000 0.00000 + 3 14 19 38 + 7 16 51 23 61 10 12 29 + + 1.00000 4.50000 + 4 33 36 39 34 + 0.00000 0.00000 0.00000 + 2 1 50 + 6 19 44 21 10 12 32 + + 5.66667 1.66667 + 3 21 9 22 + 0.00000 0.00000 0.00000 + 2 3 39 + 5 24 57 27 63 23 + + 3.00000 3.66667 + 3 23 40 37 + 0.00000 0.00000 0.00000 + 3 19 24 31 + 6 23 61 10 29 1 45 + + 4.00000 3.50000 + 4 40 23 22 41 + 0.00000 0.00000 0.00000 + 2 5 24 + 6 23 63 61 1 45 47 + + 4.75000 4.50000 + 4 41 22 53 42 + 0.00000 0.00000 0.00000 + 3 5 36 41 + 7 23 63 1 47 38 34 50 + + 6.00000 4.50000 + 4 22 9 8 53 + 0.00000 0.00000 0.00000 + 3 39 41 64 + 7 22 24 57 23 63 34 50 + + 3.00000 4.50000 + 4 37 40 43 38 + 0.00000 0.00000 0.00000 + 2 31 45 + 6 10 29 32 1 45 38 + + 1.00000 5.33333 + 3 45 34 39 + 0.00000 0.00000 -0.00000 + 3 4 50 65 + 6 19 21 12 32 6 20 + + 2.00000 5.50000 + 4 45 39 38 52 + 0.00000 0.00000 0.00000 + 3 4 54 57 + 7 29 32 12 6 20 34 49 + + 3.00000 5.33333 + 3 38 43 52 + 0.00000 0.00000 0.00000 + 3 17 45 54 + 6 29 32 38 45 34 49 + + 4.00000 5.50000 + 4 53 52 43 42 + 0.00000 0.00000 0.00000 + 2 17 36 + 6 38 47 45 34 49 50 + + 5.66667 7.33333 + 3 8 54 53 + 0.00000 0.00000 0.00000 + 2 20 64 + 5 22 24 34 50 0 + + -5.66667 7.33333 + 3 51 3 48 + -0.00000 0.00000 0.00000 + 2 7 48 + 5 48 52 43 60 30 + + 2.00000 6.50000 + 4 52 55 46 45 + 0.00000 0.00000 0.00000 + 2 57 67 + 6 6 20 58 34 49 0 + + -2.00000 7.66667 + 3 4 50 47 + -0.00000 0.00000 -0.00000 + 3 18 28 63 + 6 14 52 15 54 28 30 + + -1.00000 11.00000 + 4 4 56 57 5 + 0.00000 0.00000 0.00000 + 3 2 47 53 + 3 14 52 37 + + -4.25000 8.00000 + 4 51 50 4 3 + 0.00000 0.00000 0.00000 + 2 7 63 + 6 48 52 14 28 30 43 + + 2.00000 7.66667 + 3 55 7 46 + 0.00000 0.00000 -0.00000 + 3 25 51 67 + 6 5 22 20 58 0 49 + + 0.75000 8.00000 + 4 46 7 56 58 + 0.00000 0.00000 0.00000 + 3 10 51 61 + 5 5 22 20 58 54 + + 4.25000 8.00000 + 4 54 8 7 55 + 0.00000 0.00000 0.00000 + 2 20 25 + 6 5 22 24 0 50 49 + + 1.00000 11.00000 + 4 6 57 56 7 + 0.00000 0.00000 0.00000 + 3 10 43 53 + 3 5 39 22 + + -0.75000 8.00000 + 4 58 56 4 47 + 0.00000 0.00000 0.00000 + 3 28 47 61 + 5 14 52 15 54 58 + + 2.00000 2.50000 + 4 14 13 20 23 + 0.00000 0.00000 0.00000 + 2 8 38 + 6 35 51 16 27 61 23 + + -4.25000 1.00000 + 4 16 2 1 17 + 0.00000 0.00000 0.00000 + 2 0 58 + 6 13 56 48 4 18 11 + + -2.00000 1.33333 + 3 1 12 17 + -0.00000 0.00000 0.00000 + 3 0 6 13 + 6 13 56 46 59 11 18 + + -2.00000 2.50000 + 4 18 17 12 15 + 0.00000 0.00000 0.00000 + 2 6 56 + 6 46 59 16 11 18 2 + + -0.75000 1.00000 + 4 59 60 12 1 + 0.00000 0.00000 0.00000 + 3 12 13 33 + 5 13 56 46 59 35 + + 1.00000 -2.00000 + 4 11 10 59 61 + 0.00000 0.00000 0.00000 + 2 9 66 + 4 53 57 40 3 + + 2.00000 1.33333 + 3 10 20 13 + 0.00000 0.00000 0.00000 + 3 8 11 32 + 6 53 57 35 51 27 61 + + 4.25000 1.00000 + 4 21 20 10 9 + 0.00000 0.00000 0.00000 + 2 3 32 + 6 24 57 53 27 61 63 + + 0.75000 1.00000 + 4 13 60 59 10 + 0.00000 0.00000 0.00000 + 3 11 33 66 + 5 53 57 35 51 59 + + -1.00000 -2.00000 + 4 61 59 1 0 + 0.00000 0.00000 0.00000 + 2 9 12 + 4 3 56 13 40 + + -2.71861 21.24725 + 4 5 57 63 62 + 0.00000 0.00000 0.00000 + 3 2 23 62 + 3 14 37 26 + + 2.71861 21.24725 + 4 57 6 64 63 + 0.00000 0.00000 0.00000 + 3 23 43 49 + 3 5 39 31 + + -4.43722 38.18045 + 4 62 63 66 65 + 0.00000 0.00000 0.00000 + 2 29 62 + 4 26 37 25 36 + + 4.43722 38.18045 + 4 63 64 67 66 + 0.00000 0.00000 0.00000 + 2 29 49 + 4 31 39 25 36 diff --git a/examples/core/goalDistance.xml b/examples/core/goalDistance.xml new file mode 100644 index 00000000..407496ef --- /dev/null +++ b/examples/core/goalDistance.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/goalDistance/goalDistanceB.xml b/examples/core/goalDistance/goalDistanceB.xml new file mode 100644 index 00000000..f93e5757 --- /dev/null +++ b/examples/core/goalDistance/goalDistanceB.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/goalDistance/goalDistanceS.xml b/examples/core/goalDistance/goalDistanceS.xml new file mode 100644 index 00000000..821a870a --- /dev/null +++ b/examples/core/goalDistance/goalDistanceS.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/goalDistance/goalDistanceV.xml b/examples/core/goalDistance/goalDistanceV.xml new file mode 100644 index 00000000..ccf76c42 --- /dev/null +++ b/examples/core/goalDistance/goalDistanceV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/goalDistance/ring.nav b/examples/core/goalDistance/ring.nav new file mode 100644 index 00000000..5af90cb0 --- /dev/null +++ b/examples/core/goalDistance/ring.nav @@ -0,0 +1,227 @@ +42 + 19.00635 -1.32969 + 18.18456 -3.85892 + 16.62141 -6.01041 + 14.46992 -7.57356 + 11.94069 -8.39535 + 9.28131 -8.39535 + 6.75208 -7.57356 + 4.60059 -6.01041 + 3.03745 -3.85892 + 2.21565 -1.32969 + 2.21565 1.32969 + 3.03745 3.85892 + 4.60059 6.01041 + 6.75208 7.57356 + 9.28131 8.39535 + 11.94069 8.39535 + 14.46992 7.57356 + 16.62141 6.01041 + 18.18456 3.85892 + 19.00635 1.32969 + 23.54972 -2.04929 + 22.28319 -5.94728 + 19.87411 -9.26310 + 16.55828 -11.67219 + 12.66029 -12.93872 + 8.56171 -12.93872 + 4.66373 -11.67219 + 1.34790 -9.26310 + -1.06119 -5.94728 + -2.32772 -2.04929 + -2.32772 2.04929 + -1.06119 5.94728 + 1.34790 9.26310 + 4.66372 11.67219 + 8.56171 12.93872 + 12.66029 12.93872 + 16.55828 11.67219 + 19.87411 9.26310 + 22.28319 5.94728 + 23.54972 2.04929 + 2.30503 -1.75869 + -2.23834 -2.47829 +19 + 13 33 11 12 + 1 21 0 1 + 0 20 0 18 + 2 22 1 2 + 8 28 7 19 + 17 37 15 16 + 10 30 8 9 + 16 36 14 15 + 11 31 9 10 + 12 32 10 11 + 5 25 4 5 + 18 38 16 17 + 4 24 3 4 + 14 34 12 13 + 3 23 2 3 + 6 26 5 6 + 7 27 6 7 + 19 39 17 18 + 15 35 13 14 +42 + 22 23 2 27 + 6 5 5 22 + 28 41 19 3 + 41 40 19 35 + 9 29 8 8 + 30 31 9 10 + 14 13 12 37 + 17 16 15 23 + 29 30 8 5 + 11 10 9 24 + 31 32 10 21 + 19 18 17 31 + 2 1 1 29 + 7 6 6 1 + 20 21 0 32 + 12 11 10 9 + 25 26 5 30 + 39 20 18 14 + 33 34 12 40 + 27 28 7 2 + 36 37 15 41 + 32 33 11 18 + 5 4 4 39 + 16 15 14 38 + 10 9 8 4 + 3 2 2 12 + 38 39 17 17 + 23 24 3 36 + 35 36 14 20 + 1 0 0 34 + 26 27 6 19 + 18 17 16 7 + 21 22 1 0 + 8 7 7 13 + 0 19 18 11 + 40 8 19 33 + 24 25 4 16 + 13 12 11 15 + 15 14 13 6 + 4 3 3 25 + 34 35 13 28 + 37 38 16 26 +defaultGrp +20 + 20.75595 -3.29630 + 4 1 0 20 21 + 0.00000 0.00000 0.00000 + 2 1 2 + 6 29 34 12 14 17 32 + + 19.24082 -6.26993 + 4 2 1 21 22 + 0.00000 0.00000 0.00000 + 2 1 3 + 6 12 29 25 14 32 0 + + 16.88093 -8.62981 + 4 3 2 22 23 + 0.00000 0.00000 0.00000 + 2 3 14 + 6 12 25 39 0 32 27 + + 13.90730 -10.14495 + 4 4 3 23 24 + 0.00000 0.00000 0.00000 + 2 12 14 + 6 25 39 22 0 27 36 + + 10.61100 -10.66704 + 4 5 4 24 25 + 0.00000 0.00000 0.00000 + 2 10 12 + 6 22 39 1 27 36 16 + + 7.31471 -10.14495 + 4 6 5 25 26 + 0.00000 0.00000 0.00000 + 2 10 15 + 6 1 22 13 16 36 30 + + 4.34108 -8.62981 + 4 7 6 26 27 + 0.00000 0.00000 0.00000 + 2 15 16 + 6 1 13 33 16 30 19 + + 1.98119 -6.26993 + 4 8 7 27 28 + 0.00000 0.00000 0.00000 + 2 4 16 + 6 13 33 35 19 30 2 + + -0.05603 -0.00000 + 4 10 9 29 30 + 0.00000 0.00000 0.00000 + 1 6 + 5 4 24 9 8 5 + + 0.46605 3.29629 + 4 11 10 30 31 + 0.00000 0.00000 0.00000 + 2 6 8 + 6 9 24 15 5 8 10 + + 1.98119 6.26993 + 4 12 11 31 32 + 0.00000 0.00000 0.00000 + 2 8 9 + 6 9 15 37 5 10 21 + + 4.34108 8.62981 + 4 13 12 32 33 + 0.00000 0.00000 0.00000 + 2 0 9 + 6 15 37 6 10 21 18 + + 7.31471 10.14495 + 4 14 13 33 34 + 0.00000 0.00000 0.00000 + 2 0 13 + 6 6 37 38 18 21 40 + + 10.61100 10.66704 + 4 15 14 34 35 + 0.00000 0.00000 0.00000 + 2 13 18 + 6 6 38 23 18 40 28 + + 13.90730 10.14496 + 4 16 15 35 36 + 0.00000 0.00000 0.00000 + 2 7 18 + 6 23 38 7 28 40 20 + + 16.88093 8.62981 + 4 17 16 36 37 + 0.00000 0.00000 0.00000 + 2 5 7 + 6 7 23 31 20 28 41 + + 19.24082 6.26993 + 4 18 17 37 38 + 0.00000 0.00000 0.00000 + 2 5 11 + 6 7 31 11 20 41 26 + + 20.75596 3.29630 + 4 19 18 38 39 + 0.00000 0.00000 0.00000 + 2 11 17 + 6 11 31 34 26 41 17 + + 21.27804 0.00000 + 4 0 19 39 20 + 0.00000 0.00000 0.00000 + 2 2 17 + 6 29 34 11 14 17 26 + + 0.51074 -3.51080 + 4 8 28 41 40 + 0.00000 0.00000 0.00000 + 1 4 + 5 33 35 2 19 3 diff --git a/examples/core/headon.xml b/examples/core/headon.xml new file mode 100644 index 00000000..4e74e585 --- /dev/null +++ b/examples/core/headon.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/headon/headonB.xml b/examples/core/headon/headonB.xml new file mode 100644 index 00000000..a2f3fc4a --- /dev/null +++ b/examples/core/headon/headonB.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/headon/headonS.xml b/examples/core/headon/headonS.xml new file mode 100644 index 00000000..903352ab --- /dev/null +++ b/examples/core/headon/headonS.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/headon/headonV.xml b/examples/core/headon/headonV.xml new file mode 100644 index 00000000..71d86485 --- /dev/null +++ b/examples/core/headon/headonV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/maze-navmesh.xml b/examples/core/maze-navmesh.xml new file mode 100644 index 00000000..e31d326e --- /dev/null +++ b/examples/core/maze-navmesh.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/maze-roadmap.xml b/examples/core/maze-roadmap.xml new file mode 100644 index 00000000..1f9fabda --- /dev/null +++ b/examples/core/maze-roadmap.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/maze-vectorfield.xml b/examples/core/maze-vectorfield.xml new file mode 100644 index 00000000..286b8d77 --- /dev/null +++ b/examples/core/maze-vectorfield.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/maze/maze.nav b/examples/core/maze/maze.nav new file mode 100644 index 00000000..83da05c8 --- /dev/null +++ b/examples/core/maze/maze.nav @@ -0,0 +1,3205 @@ +537 + -24.00000 -24.00000 + -24.00000 -21.00000 + 24.00000 7.00000 + -21.00000 -24.00000 + -23.00000 -21.00000 + -21.00000 -21.00000 + -22.00000 -21.00000 + -23.00000 -19.50000 + -22.00000 -20.00000 + -22.00000 -19.00000 + -23.00000 -17.50000 + -22.00000 -18.00000 + -22.00000 -17.00000 + -23.00000 -2.00000 + -22.00000 -1.00000 + -23.00000 -1.00000 + -24.00000 -2.00000 + -23.00000 5.00000 + -24.00000 5.50000 + -23.00000 6.00000 + -23.00000 13.00000 + -24.00000 14.00000 + -17.50000 13.00000 + -18.00000 14.00000 + -17.00000 14.00000 + -11.00000 13.00000 + -10.50000 14.00000 + -10.00000 13.00000 + -18.00000 -20.00000 + -17.00000 -19.00000 + -18.00000 -23.00000 + -17.00000 -23.00000 + -17.50000 -24.00000 + -19.00000 -23.00000 + -20.00000 -24.00000 + -19.00000 -21.00000 + -20.00000 -21.00000 + -16.00000 -18.00000 + -16.00000 -17.00000 + -15.00000 -17.50000 + -16.00000 -13.00000 + -15.00000 -13.00000 + -16.00000 -22.00000 + -15.00000 -21.00000 + -5.00000 -23.00000 + -4.00000 -24.00000 + -7.00000 -21.00000 + -6.00000 -22.00000 + -7.00000 -20.00000 + -6.00000 -19.00000 + -5.00000 -18.50000 + -4.00000 -19.00000 + -4.00000 -18.00000 + -5.00000 -14.00000 + -4.00000 -14.00000 + -14.00000 -20.00000 + -13.00000 -19.00000 + -13.00000 -15.00000 + -14.00000 -14.50000 + -13.00000 -14.00000 + -13.00000 -11.00000 + -14.00000 -12.00000 + -17.00000 -12.00000 + -17.50000 -11.00000 + -18.00000 -12.00000 + -20.00000 -12.00000 + -21.00000 -11.00000 + -20.00000 -15.00000 + -21.00000 -16.00000 + -18.00000 -15.00000 + -17.00000 -16.00000 + -12.00000 -15.00000 + -12.00000 -14.00000 + -11.00000 -14.50000 + -12.00000 -18.00000 + -11.00000 -17.00000 + -8.00000 -17.00000 + -7.50000 -18.00000 + -7.00000 -17.00000 + -6.00000 -17.00000 + -6.00000 -18.00000 + -8.00000 -12.00000 + -7.00000 -13.00000 + -3.00000 -13.00000 + -2.00000 -12.00000 + -3.00000 -17.00000 + -2.00000 -16.00000 + 12.00000 -19.00000 + 13.00000 -18.00000 + 12.00000 -23.00000 + 13.00000 -23.00000 + 12.50000 -24.00000 + 11.00000 -23.00000 + 10.50000 -24.00000 + 10.00000 -23.00000 + -2.00000 -23.00000 + -3.00000 -24.00000 + -2.00000 -21.99999 + -3.00000 -21.00000 + 5.00000 -21.99999 + 4.00000 -21.00000 + 5.00000 -21.00000 + 4.00000 -20.00000 + 10.00000 -21.00000 + 11.00000 -20.00000 + -12.00000 -10.00000 + -11.00000 -9.00000 + -21.00000 -10.00000 + -20.00000 -9.00000 + -20.00000 -8.00000 + -21.00000 -7.50000 + -20.00000 -7.00000 + -20.00000 -6.00000 + -21.00000 -5.50000 + -10.00000 -8.00000 + -9.00000 -7.00000 + -10.00000 -16.00000 + -9.00000 -16.00000 + -20.00000 -5.00000 + -20.00000 1.00000 + -21.00000 0.00000 + -21.00000 1.00000 + -21.99999 0.00000 + -21.00000 5.50000 + -21.99999 5.00000 + -21.99999 6.00000 + -21.00000 12.00000 + -21.99999 12.00000 + 3.00000 -16.00000 + 3.50000 -17.00000 + 4.00000 -16.00000 + 13.00000 -16.00000 + 13.00000 -17.00000 + 3.00000 -10.00000 + 4.00000 -9.00000 + 1.00000 -10.00000 + -0.00000 -9.00000 + -0.00000 -10.00000 + -0.00000 -11.00000 + 1.00000 -15.00000 + -0.00000 -15.00000 + -6.00000 -10.00000 + -6.50000 -11.00000 + -7.00000 -10.00000 + -8.00000 -10.00000 + -8.00000 -11.00000 + -6.00000 -9.00000 + -7.00000 -8.50000 + -6.00000 -8.00000 + -6.00000 -7.00000 + -7.00000 -7.00000 + -1.00000 -9.00000 + -2.00000 -8.00000 + -1.00000 -8.00000 + -2.00000 -7.00000 + 1.00000 -8.00000 + 1.00000 -7.00000 + 23.00000 -23.00000 + 24.00000 -24.00000 + 23.00000 -21.00000 + 24.00000 -20.00000 + 14.00000 -21.00000 + 14.00000 -20.00000 + -18.50000 -6.00000 + -19.00000 -5.00000 + -18.00000 -5.00000 + -16.50000 -6.00000 + -17.00000 -5.00000 + -16.00000 -5.00000 + -14.50000 -6.00000 + -15.00000 -5.00000 + -14.00000 -5.00000 + -8.50000 -6.00000 + -9.00000 -5.00000 + -8.00000 -5.00000 + 1.00000 -6.00000 + 0.00000 -5.00000 + -19.00000 3.00000 + -18.00000 3.00000 + -17.00000 4.00000 + -16.00000 5.00000 + -20.00000 4.00000 + -20.00000 5.00000 + -15.00000 6.00000 + -14.00000 7.00000 + -20.00000 6.00000 + -19.00000 7.00000 + -19.00000 11.00000 + -20.00000 12.00000 + -10.00000 11.00000 + -11.00000 12.00000 + -7.00000 13.00000 + -7.00000 14.00000 + -18.00000 15.00000 + -17.00000 15.00000 + -17.50000 16.00000 + -24.00000 15.00000 + -23.00000 16.00000 + -23.00000 18.00000 + -24.00000 19.00000 + -21.99999 18.00000 + -21.99999 19.00000 + -21.00000 18.00000 + -21.00000 19.00000 + -20.00000 18.00000 + -19.00000 19.00000 + -19.00000 18.00000 + -21.99999 17.00000 + -21.00000 17.00000 + -20.00000 17.00000 + -16.00000 18.00000 + -15.00000 17.00000 + -16.00000 19.00000 + -15.00000 19.00000 + -15.50000 20.00000 + -18.00000 19.00000 + -17.00000 20.00000 + -17.00000 21.00000 + -18.00000 21.00000 + -21.99999 21.00000 + -21.00000 20.00000 + -19.00000 20.00000 + -20.00000 21.00000 + -20.00000 21.99999 + -19.00000 21.99999 + -19.50000 23.00000 + -23.00000 21.99999 + -23.00000 23.00000 + -24.00000 22.50000 + -23.00000 24.00000 + -24.00000 24.00000 + -23.00000 20.00000 + -24.00000 20.00000 + -17.00000 21.99134 + -18.00000 23.00000 + -17.00000 23.00000 + -18.00000 24.00000 + -10.00000 24.00000 + -11.00000 19.00000 + -12.00000 20.00000 + -12.00000 21.00000 + -11.00000 22.00000 + -16.00000 21.00000 + -16.00000 22.00000 + -13.50000 15.00000 + -14.00000 16.00000 + -13.00000 16.00000 + -6.00000 15.00000 + -6.00000 16.00000 + -14.00000 18.00000 + -13.00000 17.00000 + -9.50000 17.00000 + -10.00000 18.00000 + -9.00000 18.00000 + -5.00000 17.00000 + -5.00000 18.00000 + -9.00000 23.00000 + 0.00000 23.00000 + 1.00000 24.00000 + 0.00000 22.00000 + 1.00000 21.50000 + 0.00000 21.00000 + 0.00000 19.00000 + 1.00000 19.00000 + -2.00000 22.00000 + -1.00000 21.00000 + -1.00000 18.00000 + -2.00000 17.00000 + 4.00000 18.00000 + 3.00000 17.00000 + 3.00000 11.00000 + 4.00000 10.00000 + -2.00000 11.00000 + -1.00000 10.00000 + -1.00000 7.00000 + -2.00000 7.00000 + -1.50000 6.00000 + -9.00000 7.00000 + -8.00000 6.00000 + -8.00000 5.00000 + -9.00000 4.50000 + -8.00000 4.00000 + -8.00000 1.00000 + -9.00000 0.00000 + -7.00000 1.00000 + -6.00000 0.00000 + -2.00000 5.00000 + -3.00000 4.00000 + -3.00000 1.00000 + -2.00000 0.00000 + -4.00000 1.00000 + -5.00000 0.00000 + -7.00000 3.00000 + -6.00000 3.00000 + -4.00000 3.00000 + -5.00000 3.00000 + 4.00000 7.00000 + 3.00000 6.00000 + 3.00000 2.50000 + 4.00000 3.00000 + 4.00000 2.00000 + 3.00000 1.00000 + 4.00000 1.00000 + 3.50000 0.00000 + 6.00000 1.00000 + 6.00000 0.00000 + 2.00000 1.00000 + 1.00000 0.00000 + 2.00000 5.00000 + 1.00000 4.00000 + 0.00000 4.00000 + -1.00000 5.00000 + 0.00000 -1.00000 + -1.00000 -1.00000 + -0.50000 -2.00000 + -2.00000 -1.00000 + -2.00000 -2.00000 + 9.00000 -1.00000 + 8.00000 -2.00000 + 8.00000 -3.00000 + 9.00000 -4.00000 + 2.00000 -3.00000 + 3.00000 -4.00000 + 3.00000 -7.00000 + 2.00000 -8.00000 + 6.00000 -7.00000 + 5.00000 -8.00000 + 5.00000 -15.00000 + 6.00000 -14.00000 + 15.00000 -14.00000 + 14.00000 -15.00000 + 14.00000 -16.50000 + 15.00000 -16.00000 + 15.00000 -17.00000 + 14.00000 -19.00000 + 15.00000 -18.00000 + 16.00000 -16.00000 + 16.50000 -17.00000 + 17.00000 -16.00000 + 21.00000 -16.00000 + 22.00000 -17.00000 + 21.00000 -15.00000 + 22.00000 -14.00000 + 17.00000 -15.00000 + 16.00000 -14.00000 + 23.00000 -18.00000 + 24.00000 -19.00000 + 22.99998 -9.00000 + 23.99998 -8.00000 + 22.00000 -9.00000 + 20.99999 -8.00001 + 22.00002 -13.00000 + 21.00001 -12.00000 + 12.00000 -12.00004 + 11.00000 -13.00005 + 11.99998 -8.49999 + 10.99998 -9.00000 + 10.99997 -8.00000 + 11.99997 -6.00000 + 10.99998 -6.00000 + 11.99996 -5.00000 + 10.99997 -5.00000 + 19.00000 -5.99996 + 19.99996 -4.99995 + 19.00002 -10.00000 + 19.99999 -11.00000 + 12.99999 -10.00002 + 13.00000 -11.00003 + 10.00000 -9.00000 + 9.99999 -8.00001 + 8.99998 -8.50001 + 9.99999 -7.00000 + 8.99997 -7.00000 + 10.00002 -13.00000 + 9.00000 -12.00000 + 8.00000 -12.00000 + 7.00003 -13.00001 + 7.99997 -6.00000 + 7.00000 -6.00000 + 7.49998 -5.00001 + 4.00000 -6.00002 + 4.00000 -5.00003 + 10.00000 -5.99999 + 10.00000 -5.00000 + 9.99998 -0.00000 + 10.99998 0.00000 + 10.49998 1.00000 + 7.00000 -0.00000 + 7.00000 1.00000 + 12.00000 0.00000 + 12.50000 1.00000 + 13.00000 0.00000 + 19.00000 0.00000 + 20.00000 1.00000 + 19.00000 -1.00000 + 20.00000 -2.00000 + 14.00000 -1.00000 + 14.00000 -2.00000 + 12.00000 -4.00000 + 13.00000 -3.00000 + 21.00000 -3.00000 + 21.00000 -4.00000 + 21.99999 -3.50000 + 21.00000 -7.00000 + 21.99999 -6.00000 + 23.99999 -6.00000 + 23.99999 -7.00000 + 20.99999 2.00000 + 21.99999 2.50000 + 20.99999 3.00000 + 20.99999 4.00000 + 21.99999 5.00000 + 10.99998 2.00000 + 12.00000 3.00000 + 12.00000 8.00000 + 10.99998 8.00000 + 13.00000 4.00000 + 14.00000 5.00000 + 14.00000 13.00000 + 13.00000 12.00000 + 9.00000 12.00000 + 10.00000 13.00000 + 10.00000 16.00000 + 9.00000 17.00000 + 21.50000 16.00000 + 21.00000 17.00000 + 21.99999 17.00000 + 23.00000 16.00000 + 24.00000 17.00000 + 23.00000 9.00000 + 24.00000 8.00000 + 20.50000 9.00000 + 21.00000 8.00000 + 20.00000 8.00000 + 18.00000 9.00000 + 17.00000 8.00000 + 18.00000 14.00000 + 17.00000 14.00000 + 17.50000 15.00000 + 11.00000 14.00000 + 11.00000 15.00000 + 21.00000 14.00000 + 22.00000 15.00000 + 21.00000 11.00000 + 22.00000 10.00000 + 20.00000 11.00000 + 19.00000 10.00000 + 20.00000 13.00000 + 18.99999 13.00000 + 21.00000 7.00000 + 20.00000 7.00000 + 20.50000 6.00000 + 16.00000 7.00000 + 15.00000 6.00000 + 16.00000 13.00000 + 15.00000 13.00000 + 23.00000 6.00000 + 23.00000 -5.00000 + 24.00000 -5.00000 + 21.00000 18.00000 + 21.99999 18.00000 + 21.50000 19.00000 + 24.00000 18.00000 + 23.00000 19.00000 + 23.00000 20.00000 + 24.00000 20.50000 + 23.00000 21.00000 + 23.00000 23.00000 + 24.00000 23.50000 + 23.00000 24.00000 + 22.99474 25.00000 + 23.99474 25.00000 + 14.62844 25.81261 + 32.36104 25.81261 + 14.62844 33.59634 + 32.36104 33.59634 + 3.00000 23.00000 + 2.00000 24.00000 + 3.00000 20.00000 + 2.00000 19.00000 + 5.50000 20.00000 + 5.00000 19.00000 + 6.00000 19.00000 + 7.50000 20.00000 + 7.00000 19.00000 + 8.00000 19.00000 + 12.00000 20.00000 + 11.00000 19.00000 + 11.00000 18.00000 + 12.00000 18.00000 + 15.00000 20.00000 + 15.00000 21.00000 + 13.00000 18.00000 + 14.00000 19.00000 + 14.00000 22.00000 + 13.00000 21.00000 + 4.00000 21.00001 + 4.00000 22.00001 + 9.00000 3.00000 + 10.00000 2.00000 + 9.00000 4.00000 + 10.00000 4.50000 + 9.00000 5.00000 + 9.00000 6.00000 + 10.00000 7.00000 + 6.00000 6.00000 + 5.00000 7.00000 + 6.00000 4.00000 + 5.00000 4.00000 + 7.00000 4.00000 + 7.00000 5.00000 + -9.00000 -1.00000 + -8.00000 -2.00000 + -4.00000 -2.00000 + -3.00000 -1.00000 + -4.00000 -3.00000 + -3.00000 -3.00000 + -3.50000 -4.00000 + -7.00000 -3.00000 + -7.00000 -4.00000 + 1.00000 -3.00000 + 0.00000 -4.00000 + 7.00000 10.00000 + 8.00000 11.00000 + 12.00000 11.00000 + 11.00000 10.00000 + 11.00000 9.00000 + 12.00000 9.00000 + 5.00000 9.00000 + 6.00000 9.00000 + 5.50000 8.00000 + 10.00000 9.00000 + 10.00000 8.00000 + 0.00000 9.00000 + 0.00000 8.00000 + -11.00000 23.00000 + -11.00000 24.00000 +309 + 193 195 112 113 + 62 64 34 38 + 356 357 201 207 + 18 19 8 9 + 332 333 187 189 + 412 413 233 234 + 112 113 63 66 + 2 456 257 258 + 105 106 59 60 + 57 59 31 39 + 142 143 82 83 + 503 504 284 285 + 501 502 283 284 + 55 56 29 30 + 33 34 17 18 + 72 73 40 59 + 462 463 261 262 + 109 110 61 62 + 327 328 184 185 + 394 395 223 224 + 400 402 227 230 + 459 461 260 278 + 323 324 182 183 + 206 209 119 120 + 467 469 265 269 + 325 326 183 184 + 245 246 139 141 + 60 61 32 33 + 384 385 217 218 + 515 516 290 291 + 483 484 273 274 + 58 59 31 32 + 445 446 251 252 + 20 21 9 10 + 418 419 236 237 + 103 104 57 58 + 336 337 189 190 + 76 78 43 45 + 329 330 185 186 + 50 51 26 27 + 470 471 266 267 + 389 391 221 225 + 313 314 177 178 + 76 77 42 43 + 529 530 299 300 + 74 75 41 42 + 432 433 244 253 + 464 466 263 277 + 89 91 50 51 + 226 227 129 130 + 520 521 293 294 + 351 352 198 199 + 345 346 195 196 + 308 309 174 175 + 23 24 11 111 + 153 154 88 89 + 389 390 220 221 + 528 530 299 301 + 259 261 148 150 + 167 168 96 103 + 42 43 22 24 + 157 158 90 91 + 141 143 82 84 + 382 383 215 216 + 90 91 50 90 + 299 300 169 281 + 213 214 122 135 + 464 465 262 263 + 522 523 295 296 + 71 72 39 40 + 392 393 222 223 + 129 130 74 75 + 472 473 267 268 + 364 365 205 206 + 63 64 34 35 + 275 276 156 157 + 10 12 4 5 + 15 16 6 7 + 347 348 196 197 + 385 386 218 220 + 147 148 85 86 + 349 350 197 198 + 431 433 244 245 + 194 195 112 138 + 500 502 283 287 + 87 88 48 49 + 494 495 279 280 + 7 9 2 3 + 97 98 54 55 + 358 359 202 203 + 185 186 106 107 + 270 271 153 154 + 251 252 142 143 + 384 386 218 219 + 37 39 20 22 + 244 246 139 140 + 189 190 108 109 + 515 517 291 292 + 146 147 84 85 + 400 401 226 227 + 312 313 176 177 + 166 168 96 97 + 460 461 260 261 + 107 108 60 61 + 37 38 19 20 + 378 379 213 214 + 169 170 97 98 + 114 115 64 65 + 183 184 105 106 + 240 241 136 137 + 173 174 100 288 + 30 31 15 16 + 478 479 270 271 + 436 438 247 249 + 22 23 10 11 + 484 485 274 295 + 8 9 2 14 + 113 118 66 67 + 65 66 35 36 + 92 94 52 58 + 500 501 282 283 + 334 335 188 195 + 200 202 116 118 + 468 469 265 266 + 219 220 125 126 + 272 273 154 155 + 172 174 100 101 + 301 303 171 173 + 279 280 158 159 + 434 435 245 246 + 38 39 20 21 + 443 444 250 251 + 50 52 27 28 + 28 29 14 15 + 362 363 204 205 + 355 357 201 202 + 288 289 163 164 + 424 426 240 241 + 226 228 130 132 + 119 120 67 68 + 123 125 70 71 + 128 129 73 74 + 135 136 77 78 + 266 267 151 152 + 133 134 76 77 + 319 320 180 181 + 257 258 146 147 + 377 378 212 213 + 212 214 122 123 + 99 100 55 56 + 321 322 181 182 + 101 102 56 57 + 109 111 62 64 + 62 63 33 34 + 198 199 114 115 + 11 12 4 19 + 48 49 25 29 + 282 283 160 161 + 441 442 249 250 + 244 245 138 139 + 436 437 246 247 + 368 370 208 210 + 260 261 148 149 + 449 451 254 257 + 238 239 135 136 + 202 203 116 117 + 223 224 127 128 + 44 45 23 26 + 51 52 27 48 + 467 468 264 265 + 25 26 12 13 + 164 165 94 102 + 459 460 259 260 + 201 203 116 125 + 163 164 93 94 + 146 148 85 87 + 401 402 227 228 + 516 517 291 293 + 425 426 240 259 + 237 256 145 146 + 17 18 7 8 + 296 297 167 168 + 528 529 298 299 + 437 438 247 248 + 227 228 130 131 + 112 118 66 93 + 110 111 62 63 + 67 68 36 37 + 69 70 37 38 + 277 278 157 158 + 193 194 111 112 + 424 425 239 240 + 268 269 152 153 + 452 453 255 256 + 135 138 79 80 + 483 485 274 275 + 450 451 254 255 + 336 338 190 194 + 369 370 208 209 + 306 307 173 174 + 83 84 46 47 + 71 73 40 41 + 166 167 95 96 + 4 6 0 1 + 85 86 47 73 + 259 260 147 148 + 57 58 30 31 + 172 173 99 100 + 298 299 168 169 + 210 211 120 121 + 212 213 121 122 + 339 340 191 192 + 480 481 271 272 + 124 125 70 72 + 498 499 281 282 + 480 482 272 273 + 233 234 133 134 + 377 379 213 215 + 179 180 103 104 + 251 253 143 144 + 505 506 285 286 + 274 276 156 167 + 398 399 225 226 + 341 342 192 193 + 331 333 187 188 + 375 376 211 212 + 31 32 16 23 + 249 250 141 142 + 89 90 49 50 + 252 253 143 145 + 169 171 98 99 + 513 514 289 290 + 420 421 237 238 + 93 94 52 53 + 312 314 177 179 + 137 138 79 81 + 407 408 230 231 + 81 82 45 46 + 410 411 232 235 + 141 142 81 82 + 353 354 199 200 + 170 171 98 105 + 92 93 51 52 + 361 383 216 217 + 200 201 115 116 + 359 361 203 216 + 416 417 235 236 + 390 391 221 222 + 204 205 117 119 + 235 236 134 302 + 284 285 161 165 + 407 409 231 233 + 279 281 159 162 + 264 265 150 151 + 331 332 186 187 + 429 430 242 243 + 343 344 193 194 + 373 374 210 211 + 408 409 231 232 + 286 287 162 163 + 7 8 1 2 + 215 216 123 124 + 30 32 16 17 + 290 291 164 166 + 302 303 171 172 + 511 512 288 289 + 196 197 113 114 + 476 477 269 270 + 135 137 78 79 + 422 423 238 239 + 77 78 43 44 + 310 311 175 176 + 280 281 159 160 + 481 482 272 298 + 187 188 107 108 + 317 318 179 180 + 46 47 24 25 + 95 96 53 54 + 224 225 128 133 + 358 360 203 204 + 151 152 87 88 + 298 300 169 170 + 175 176 101 294 + 274 275 155 156 + 337 338 190 191 + 486 487 275 276 + 368 369 207 208 + 403 404 228 229 + 301 302 170 171 + 431 432 243 244 + 13 14 5 6 + 223 225 128 129 + 10 11 3 4 + 25 27 13 109 + 465 466 263 264 + 492 493 278 279 + 159 160 91 92 + 163 165 94 95 + 355 356 200 201 + 17 19 8 72 + 22 24 11 12 + 221 222 126 127 + 449 450 253 254 + 26 27 13 110 + 427 428 241 242 + 121 122 68 69 + 524 525 296 297 + 123 124 69 70 + 128 130 74 76 +537 + 390 393 222 325 + 292 293 165 136 + 168 170 97 301 + 31 44 23 418 + 147 150 86 246 + 135 139 80 47 + 145 144 83 50 + 522 484 295 327 + 312 317 179 78 + 38 40 21 259 + 485 523 295 530 + 248 247 140 108 + 283 280 160 285 + 204 202 117 247 + 281 282 160 270 + 381 379 214 437 + 419 420 237 194 + 402 404 228 348 + 85 83 47 178 + 518 515 292 116 + 124 17 72 531 + 461 463 261 105 + 508 506 286 163 + 193 196 113 308 + 456 451 257 505 + 275 272 155 276 + 148 152 87 288 + 253 255 144 486 + 368 373 210 174 + 446 448 252 93 + 222 223 127 335 + 307 309 174 341 + 498 500 282 507 + 243 241 137 522 + 160 158 91 408 + 328 329 185 172 + 249 252 142 300 + 84 86 47 227 + 100 102 56 184 + 235 233 134 125 + 162 160 92 34 + 179 181 104 144 + 467 476 269 96 + 269 267 152 212 + 360 363 204 202 + 263 262 149 323 + 421 418 237 254 + 139 140 80 231 + 174 176 101 445 + 205 206 119 157 + 144 143 83 403 + 93 96 53 450 + 358 355 202 225 + 410 416 235 487 + 316 315 178 271 + 294 290 166 387 + 521 517 293 304 + 438 442 249 164 + 9 29 14 511 + 501 499 282 64 + 291 295 166 336 + 375 374 211 208 + 325 328 184 35 + 91 93 51 51 + 499 300 281 324 + 126 123 71 201 + 98 100 55 38 + 62 70 38 423 + 52 88 48 151 + 427 424 241 380 + 298 297 168 466 + 429 427 242 69 + 92 89 51 328 + 450 433 253 498 + 471 468 266 356 + 136 134 77 413 + 399 400 226 382 + 447 445 252 409 + 317 320 180 427 + 56 49 29 236 + 526 525 297 132 + 129 85 73 18 + 395 397 224 391 + 258 260 147 219 + 4 7 1 518 + 190 25 109 277 + 55 58 30 493 + 6 5 0 326 + 81 84 46 37 + 407 412 233 329 + 414 413 234 355 + 256 253 145 27 + 107 110 61 379 + 448 447 252 77 + 279 286 162 319 + 42 37 22 523 + 476 478 270 499 + 76 81 45 88 + 207 200 118 386 + 115 117 65 229 + 335 345 195 177 + 431 429 243 71 + 120 122 68 269 + 449 2 257 472 + 491 466 277 350 + 463 464 262 309 + 324 321 182 113 + 327 326 184 421 + 247 244 140 120 + 534 533 301 360 + 240 242 137 272 + 109 108 61 294 + 505 507 286 253 + 321 319 181 173 + 510 502 287 167 + 220 203 125 481 + 515 513 290 535 + 415 414 234 90 + 489 488 276 140 + 177 178 102 534 + 244 194 138 434 + 221 220 126 115 + 73 75 41 461 + 520 175 294 491 + 512 174 288 48 + 233 224 133 170 + 36 35 18 239 + 532 530 300 401 + 482 529 298 451 + 273 274 155 243 + 386 390 220 0 + 440 438 248 57 + 525 522 296 7 + 186 184 106 180 + 430 432 243 457 + 351 354 199 211 + 293 285 165 376 + 189 187 108 366 + 201 219 125 250 + 188 190 108 85 + 488 487 276 517 + 90 157 90 292 + 536 535 302 156 + 106 73 59 122 + 181 182 104 290 + 138 142 81 255 + 434 431 245 101 + 313 311 176 191 + 387 388 219 217 + 97 95 54 402 + 528 481 298 218 + 88 90 49 141 + 118 164 93 446 + 425 459 259 476 + 41 39 21 473 + 417 411 235 186 + 535 235 302 39 + 206 210 120 480 + 13 16 6 520 + 230 229 131 262 + 74 71 41 513 + 527 526 297 80 + 171 173 99 340 + 506 504 285 249 + 442 444 250 502 + 458 457 258 206 + 87 51 48 420 + 502 503 284 283 + 469 470 266 210 + 208 207 118 98 + 224 221 127 121 + 217 216 124 414 + 329 332 186 430 + 319 318 180 359 + 373 376 211 242 + 159 161 92 337 + 479 477 270 280 + 345 347 196 318 + 83 82 46 372 + 23 193 111 23 + 184 171 105 162 + 277 275 157 25 + 33 30 17 509 + 237 258 146 83 + 102 104 57 425 + 20 19 9 310 + 411 408 232 381 + 357 359 202 516 + 409 410 232 53 + 474 475 268 316 + 254 251 144 264 + 311 308 175 508 + 199 201 115 138 + 304 305 172 519 + 420 423 238 441 + 211 209 120 234 + 310 312 176 8 + 422 421 238 46 + 495 496 280 251 + 492 495 279 198 + 1 4 0 84 + 123 121 69 452 + 363 365 205 525 + 377 375 212 61 + 111 115 64 99 + 385 361 217 338 + 457 456 258 24 + 53 54 28 455 + 374 370 210 464 + 125 127 71 334 + 470 472 267 222 + 354 356 200 258 + 267 264 151 390 + 270 269 153 43 + 346 334 195 261 + 146 141 84 303 + 153 151 88 506 + 388 386 219 130 + 481 479 271 176 + 260 263 149 45 + 453 455 256 291 + 250 246 141 298 + 472 474 268 189 + 340 337 191 315 + 236 536 302 142 + 355 353 200 263 + 215 218 124 405 + 86 128 73 383 + 276 278 157 287 + 117 116 65 284 + 405 406 229 282 + 140 138 80 145 + 57 56 30 79 + 105 107 60 92 + 209 204 119 13 + 486 489 276 118 + 49 47 25 432 + 32 34 17 411 + 497 494 280 342 + 35 33 18 182 + 232 228 132 367 + 301 298 170 70 + 376 378 212 417 + 274 296 167 484 + 271 273 154 129 + 524 527 297 161 + 150 149 86 370 + 202 208 118 169 + 436 434 246 146 + 504 501 284 59 + 219 222 126 30 + 496 497 280 238 + 299 498 281 32 + 507 508 286 22 + 418 417 236 155 + 142 145 83 6 + 338 339 191 266 + 154 156 89 410 + 356 368 207 28 + 40 41 21 154 + 303 307 173 31 + 334 331 188 368 + 229 227 131 482 + 353 352 199 353 + 251 250 142 221 + 165 167 95 369 + 339 341 192 268 + 330 327 185 107 + 341 343 193 521 + 122 124 69 20 + 282 284 161 533 + 315 313 178 147 + 242 243 137 33 + 59 72 39 514 + 480 483 273 296 + 439 440 248 131 + 272 270 154 213 + 25 22 12 331 + 382 377 215 203 + 454 452 256 394 + 477 469 269 168 + 113 120 67 102 + 406 403 229 454 + 503 505 285 112 + 116 114 65 392 + 280 277 158 181 + 465 462 262 358 + 278 279 158 94 + 152 154 88 257 + 155 153 89 216 + 182 180 104 322 + 455 454 256 279 + 157 159 91 175 + 45 32 23 237 + 108 106 60 143 + 389 385 220 205 + 483 486 275 235 + 435 437 246 313 + 246 248 140 11 + 288 287 163 399 + 252 237 145 183 + 170 183 105 378 + 519 518 292 19 + 141 137 81 503 + 517 519 292 302 + 306 301 173 241 + 322 323 182 354 + 60 59 32 273 + 196 199 114 192 + 464 490 277 474 + 19 125 72 209 + 61 62 33 67 + 369 357 207 187 + 437 439 248 275 + 426 428 241 458 + 337 333 189 416 + 475 473 268 361 + 441 436 249 248 + 347 349 197 321 + 286 289 163 433 + 493 461 278 21 + 349 351 198 135 + 180 168 103 2 + 262 261 149 497 + 300 302 170 489 + 393 395 223 82 + 5 3 0 504 + 484 482 273 128 + 89 87 49 166 + 412 415 234 117 + 99 97 55 149 + 22 20 10 185 + 21 23 10 179 + 132 129 75 81 + 127 126 71 65 + 223 226 129 442 + 295 294 166 55 + 161 162 92 40 + 361 360 203 44 + 212 215 123 226 + 173 511 288 398 + 309 310 175 196 + 494 493 279 320 + 509 510 287 114 + 166 163 95 510 + 392 391 222 384 + 514 516 290 469 + 27 189 109 137 + 404 405 229 230 + 364 362 205 388 + 466 467 264 42 + 371 369 209 312 + 119 118 67 152 + 352 350 198 444 + 323 325 183 62 + 413 409 233 188 + 468 465 264 286 + 372 371 209 351 + 462 460 261 431 + 318 314 179 456 + 533 528 301 150 + 473 471 267 74 + 50 53 28 207 + 185 188 107 139 + 366 364 206 349 + 238 213 135 495 + 187 186 107 133 + 228 230 131 159 + 331 330 186 267 + 167 179 103 41 + 149 148 86 26 + 192 191 110 448 + 82 78 45 529 + 266 268 152 385 + 80 77 44 524 + 344 342 193 426 + 285 283 161 12 + 231 232 132 240 + 183 185 106 363 + 110 113 63 281 + 424 422 239 197 + 408 402 230 17 + 400 407 230 89 + 128 133 76 463 + 391 399 225 76 + 268 271 153 244 + 200 198 115 428 + 290 288 164 299 + 362 358 204 52 + 214 239 135 424 + 264 259 150 468 + 397 396 224 512 + 114 109 64 111 + 69 64 38 532 + 452 450 255 73 + 172 169 99 453 + 401 398 226 443 + 65 67 36 479 + 511 514 289 346 + 287 281 162 14 + 63 60 33 307 + 530 534 301 109 + 95 94 53 488 + 143 147 84 4 + 383 384 217 438 + 218 217 124 171 + 46 48 25 501 + 394 392 223 345 + 158 91 90 63 + 445 443 251 485 + 156 155 89 289 + 34 36 18 126 + 257 256 146 91 + 134 130 76 536 + 216 214 123 389 + 10 13 5 158 + 333 335 188 100 + 378 380 214 515 + 44 50 26 362 + 15 14 6 483 + 51 45 26 293 + 326 324 183 106 + 0 1 0 200 + 70 68 37 467 + 239 240 136 110 + 104 92 58 72 + 342 340 192 223 + 320 322 181 306 + 198 197 114 527 + 26 192 110 371 + 332 336 189 439 + 460 426 259 314 + 47 42 24 95 + 289 291 164 60 + 194 24 111 500 + 43 46 24 406 + 28 8 14 492 + 379 383 215 404 + 384 387 219 148 + 336 344 194 375 + 531 532 300 127 + 423 425 239 153 + 226 231 132 377 + 398 389 225 295 + 350 348 197 470 + 176 521 294 56 + 164 177 102 119 + 234 236 134 224 + 191 27 110 347 + 112 111 63 204 + 96 98 54 66 + 529 531 300 440 + 121 119 68 352 + 169 166 97 344 + 403 401 228 396 + 54 52 28 68 + 314 316 178 54 + 432 449 253 103 + 428 430 242 134 + 66 63 35 400 + 18 21 9 332 + 75 76 42 97 + 131 132 75 333 + 133 135 77 5 + 370 372 209 357 + 225 234 133 447 + 297 276 167 228 + 68 66 36 459 + 259 257 147 412 + 516 520 293 123 + 348 346 196 214 + 367 366 206 364 + 2 458 258 165 + 39 43 22 435 + 490 491 277 104 + 101 99 56 330 + 459 492 278 199 + 103 101 57 475 + 11 9 3 58 + 67 69 37 393 + 210 212 121 339 + 203 205 117 49 + 227 225 129 465 + 14 12 5 526 + 296 299 168 252 + 443 441 250 317 + 255 254 144 190 + 416 419 236 16 + 94 103 58 477 + 302 304 172 193 + 245 249 141 36 + 175 172 101 395 + 8 6 1 87 + 58 61 32 311 + 195 245 138 490 + 213 211 121 195 + 79 80 44 374 + 261 265 150 528 + 433 435 245 297 + 478 480 271 274 + 24 26 12 429 + 48 55 29 86 + 444 446 251 29 + 137 136 78 75 + 3 0 0 422 + 451 453 255 220 + 151 146 87 215 + 500 509 287 343 + 308 306 174 305 + 30 28 15 436 + 163 112 93 449 + 29 31 15 3 + 396 394 224 407 + 71 57 39 232 + 72 105 59 233 + 380 381 214 15 + 359 382 216 278 + 487 485 275 10 + 7 10 3 415 + 305 303 172 260 + 16 18 7 460 + 343 338 194 256 + 241 238 136 365 + 37 11 19 478 + 77 74 42 160 + 365 367 206 471 + 12 38 19 9 + 197 195 113 494 + 265 266 151 373 + 78 79 44 496 + 523 524 296 245 + 17 15 7 419 + 64 65 35 397 + 284 292 165 1 + 178 165 102 265 + 513 512 289 124 + 130 131 75 462 +defaultGrp +303 + -22.50000 -22.00000 + 6 4 6 5 3 0 1 + 0.00000 -0.00000 -0.00000 + 1 203 + 7 422 504 200 326 84 87 492 + + -22.50000 -20.37500 + 4 6 4 7 8 + 0.00000 -0.00000 -0.00000 + 2 203 260 + 6 84 200 87 492 518 436 + + -22.33333 -19.50000 + 3 8 7 9 + 0.00000 -0.00000 -0.00000 + 3 87 116 260 + 6 84 518 436 492 58 478 + + -22.50000 -18.50000 + 4 9 7 10 11 + -0.00000 0.00000 -0.00000 + 2 87 292 + 6 84 518 58 478 415 523 + + -22.33333 -17.50000 + 3 11 10 12 + 0.00000 -0.00000 -0.00000 + 3 76 155 292 + 6 415 518 478 523 483 526 + + -22.50000 -9.37500 + 4 12 10 13 14 + -0.00000 -0.00000 -0.00000 + 2 76 290 + 6 415 518 483 526 158 419 + + -23.00000 -1.50000 + 4 15 14 13 16 + -0.00000 0.00000 -0.00000 + 2 77 290 + 6 158 415 419 483 531 520 + + -23.50000 1.87500 + 4 15 16 18 17 + -0.00000 0.00000 -0.00000 + 2 77 180 + 6 419 531 158 520 20 460 + + -23.33333 5.50000 + 3 17 18 19 + -0.00000 0.00000 -0.00000 + 3 3 180 299 + 6 20 531 460 520 185 310 + + -23.50000 9.62500 + 4 19 18 21 20 + 0.00000 0.00000 -0.00000 + 2 3 33 + 6 460 520 185 310 331 332 + + -20.62500 13.50000 + 4 20 21 23 22 + 0.00000 0.00000 -0.00000 + 2 33 114 + 6 185 331 332 460 277 179 + + -17.50000 13.66666 + 3 22 23 24 + 0.00000 -0.00000 -0.00000 + 3 54 114 300 + 6 277 331 179 332 434 500 + + -14.00000 13.50000 + 4 22 24 26 25 + -0.00000 0.00000 -0.00000 + 2 170 300 + 6 277 331 434 500 85 429 + + -10.50000 13.33333 + 3 25 26 27 + 0.00000 0.00000 -0.00000 + 3 170 293 303 + 6 85 277 429 500 347 448 + + -19.75000 -19.50000 + 4 8 9 29 28 + 0.00000 0.00000 -0.00000 + 2 116 133 + 6 436 492 58 478 509 511 + + -17.50000 -21.25000 + 4 28 29 31 30 + 0.00000 -0.00000 -0.00000 + 2 111 133 + 6 436 509 58 511 182 3 + + -17.50000 -23.33333 + 3 30 31 32 + 0.00000 -0.00000 -0.00000 + 3 111 226 262 + 6 182 509 3 511 237 293 + + -18.62500 -23.50000 + 4 30 32 34 33 + 0.00000 -0.00000 -0.00000 + 2 14 262 + 6 182 509 237 293 239 411 + + -19.50000 -22.25000 + 4 33 34 36 35 + 0.00000 -0.00000 -0.00000 + 1 14 + 5 182 239 237 411 126 + + -19.00000 -17.50000 + 4 11 12 38 37 + 0.00000 0.00000 -0.00000 + 2 104 155 + 6 478 523 483 526 95 9 + + -15.66667 -17.50000 + 3 37 38 39 + -0.00000 0.00000 -0.00000 + 3 94 104 130 + 6 95 523 9 526 154 473 + + -15.50000 -15.12500 + 4 39 38 40 41 + 0.00000 -0.00000 -0.00000 + 1 130 + 5 9 526 154 473 259 + + -15.50000 -19.62500 + 4 37 39 43 42 + 0.00000 -0.00000 -0.00000 + 2 60 94 + 6 95 523 154 473 432 435 + + -10.87500 -23.50000 + 4 32 31 44 45 + -0.00000 -0.00000 -0.00000 + 2 167 226 + 6 3 511 237 293 418 420 + + -11.00000 -21.50000 + 4 42 43 46 47 + 0.00000 0.00000 -0.00000 + 2 60 276 + 6 95 432 435 473 406 236 + + -6.50000 -20.50000 + 4 47 46 48 49 + -0.00000 0.00000 -0.00000 + 2 156 276 + 6 406 435 236 432 501 79 + + -4.50000 -21.12500 + 4 45 44 50 51 + 0.00000 -0.00000 -0.00000 + 2 39 167 + 6 3 418 293 420 362 166 + + -4.33333 -18.50000 + 3 51 50 52 + -0.00000 -0.00000 -0.00000 + 3 39 132 168 + 6 362 418 166 420 68 455 + + -4.50000 -16.12500 + 4 52 50 53 54 + 0.00000 -0.00000 -0.00000 + 1 132 + 5 362 418 68 455 207 + + -10.00000 -19.50000 + 4 49 48 55 56 + -0.00000 0.00000 -0.00000 + 2 13 156 + 6 406 501 79 236 86 232 + + -13.50000 -17.12500 + 4 56 55 58 57 + 0.00000 -0.00000 -0.00000 + 2 13 206 + 6 86 501 79 232 513 493 + + -13.33333 -14.50000 + 3 57 58 59 + -0.00000 -0.00000 -0.00000 + 3 9 31 206 + 6 232 513 86 493 273 307 + + -13.50000 -12.87500 + 4 59 58 61 60 + 0.00000 -0.00000 -0.00000 + 2 27 31 + 6 86 493 273 307 400 311 + + -15.37500 -11.50000 + 4 60 61 62 63 + 0.00000 -0.00000 -0.00000 + 2 27 153 + 6 307 400 311 493 67 459 + + -17.50000 -11.66667 + 3 63 62 64 + 0.00000 0.00000 -0.00000 + 3 1 74 153 + 6 67 311 400 459 393 532 + + -19.12500 -11.50000 + 4 63 64 65 66 + 0.00000 -0.00000 -0.00000 + 2 74 118 + 6 400 459 393 532 397 467 + + -20.50000 -13.50000 + 4 66 65 67 68 + 0.00000 -0.00000 -0.00000 + 2 118 187 + 6 397 532 459 467 479 423 + + -19.00000 -15.50000 + 4 68 67 69 70 + 0.00000 -0.00000 -0.00000 + 2 187 188 + 6 397 479 423 467 393 67 + + -17.50000 -13.75000 + 4 70 69 64 62 + 0.00000 -0.00000 -0.00000 + 2 1 188 + 6 67 311 393 532 479 423 + + -12.50000 -14.50000 + 4 57 59 72 71 + -0.00000 -0.00000 -0.00000 + 2 9 69 + 6 232 513 273 307 160 514 + + -11.66667 -14.50000 + 3 71 72 73 + -0.00000 0.00000 -0.00000 + 3 15 69 201 + 6 160 513 273 514 122 143 + + -11.50000 -16.12500 + 4 71 73 75 74 + 0.00000 -0.00000 -0.00000 + 2 45 201 + 6 160 513 122 143 524 461 + + -9.62500 -17.50000 + 4 74 75 76 77 + -0.00000 0.00000 -0.00000 + 2 43 45 + 6 160 524 122 461 97 374 + + -7.50000 -17.33333 + 3 77 76 78 + 0.00000 0.00000 -0.00000 + 3 37 43 270 + 6 97 461 374 524 372 529 + + -6.62500 -17.50000 + 4 77 78 79 80 + 0.00000 -0.00000 -0.00000 + 1 270 + 5 374 524 372 529 496 + + -7.50000 -14.75000 + 4 78 76 81 82 + -0.00000 0.00000 -0.00000 + 2 37 237 + 6 97 461 372 529 88 178 + + -5.00000 -12.50000 + 4 82 81 84 83 + -0.00000 0.00000 -0.00000 + 2 200 237 + 6 88 97 178 372 18 37 + + -2.50000 -14.50000 + 4 83 84 86 85 + -0.00000 0.00000 -0.00000 + 2 200 204 + 6 18 178 37 88 81 227 + + 4.25000 -18.50000 + 4 51 52 88 87 + 0.00000 -0.00000 -0.00000 + 2 85 168 + 6 166 420 68 455 328 151 + + 12.50000 -20.75000 + 4 87 88 90 89 + -0.00000 0.00000 -0.00000 + 2 85 228 + 6 166 328 68 151 72 141 + + 12.50000 -23.33333 + 3 89 90 91 + 0.00000 -0.00000 -0.00000 + 3 48 64 228 + 6 72 328 141 151 63 408 + + 11.50000 -23.50000 + 4 89 91 93 92 + -0.00000 -0.00000 -0.00000 + 2 48 242 + 6 72 328 63 408 425 51 + + 10.50000 -23.33333 + 3 92 93 94 + -0.00000 -0.00000 -0.00000 + 3 119 233 242 + 6 72 425 51 63 402 488 + + 3.87500 -23.50000 + 4 94 93 96 95 + 0.00000 0.00000 -0.00000 + 2 233 277 + 6 51 63 402 488 149 450 + + -2.50000 -22.50000 + 4 95 96 98 97 + 0.00000 0.00000 -0.00000 + 2 88 277 + 6 149 402 51 450 330 66 + + 1.00000 -21.50000 + 4 97 98 100 99 + 0.00000 -0.00000 -0.00000 + 2 88 149 + 6 149 330 66 450 475 38 + + 4.50000 -21.00000 + 4 101 99 100 102 + -0.00000 -0.00000 -0.00000 + 2 149 151 + 6 330 475 38 66 477 184 + + 7.50000 -20.50000 + 4 101 102 104 103 + -0.00000 -0.00000 -0.00000 + 2 35 151 + 6 475 477 38 184 488 425 + + 10.50000 -21.75000 + 4 103 104 92 94 + 0.00000 -0.00000 -0.00000 + 2 35 119 + 6 72 425 402 488 477 184 + + -11.50000 -11.87500 + 4 73 72 105 106 + 0.00000 -0.00000 -0.00000 + 2 8 15 + 6 273 514 122 143 233 294 + + -16.00000 -9.50000 + 4 106 105 107 108 + 0.00000 -0.00000 -0.00000 + 2 8 103 + 6 233 514 143 294 92 111 + + -20.50000 -8.62500 + 4 108 107 110 109 + 0.00000 -0.00000 -0.00000 + 2 17 103 + 6 92 233 111 294 392 379 + + -20.33333 -7.50000 + 3 109 110 111 + -0.00000 -0.00000 -0.00000 + 3 17 152 186 + 6 111 392 92 379 204 449 + + -20.50000 -6.50000 + 4 111 110 113 112 + 0.00000 -0.00000 -0.00000 + 2 6 186 + 6 92 379 204 449 510 281 + + -14.75000 -7.50000 + 4 109 111 115 114 + -0.00000 0.00000 -0.00000 + 2 107 152 + 6 111 392 204 449 284 99 + + -9.50000 -11.75000 + 4 114 115 117 116 + -0.00000 0.00000 -0.00000 + 1 107 + 5 284 392 99 204 229 + + -20.33333 -5.50000 + 3 112 113 118 + -0.00000 -0.00000 -0.00000 + 3 6 117 185 + 6 449 510 281 379 152 352 + + -20.50000 -2.37500 + 4 118 113 120 119 + 0.00000 -0.00000 -0.00000 + 2 117 139 + 6 281 379 152 352 452 102 + + -21.00000 0.50000 + 4 121 119 120 122 + 0.00000 0.00000 -0.00000 + 2 139 305 + 6 352 452 102 281 201 269 + + -21.50000 2.87500 + 4 121 122 124 123 + -0.00000 -0.00000 -0.00000 + 2 305 307 + 6 201 452 102 269 65 20 + + -21.66666 5.50000 + 3 123 124 125 + -0.00000 0.00000 -0.00000 + 3 140 213 307 + 6 65 201 20 269 209 310 + + -21.50000 8.87500 + 4 123 125 127 126 + -0.00000 -0.00000 -0.00000 + 1 140 + 5 65 201 209 310 334 + + -22.50000 5.50000 + 4 125 124 17 19 + -0.00000 -0.00000 -0.00000 + 2 213 299 + 6 20 531 185 310 269 209 + + 0.37500 -16.50000 + 4 85 86 128 129 + -0.00000 0.00000 -0.00000 + 2 141 204 + 6 18 81 37 227 383 333 + + 3.50000 -16.33333 + 3 129 128 130 + 0.00000 0.00000 -0.00000 + 3 71 141 308 + 6 227 383 81 333 413 536 + + 8.37500 -16.50000 + 4 129 130 131 132 + -0.00000 -0.00000 -0.00000 + 1 71 + 5 81 333 413 536 462 + + 3.50000 -12.75000 + 4 130 128 133 134 + 0.00000 0.00000 -0.00000 + 2 144 308 + 6 227 383 413 536 463 75 + + 2.00000 -9.50000 + 4 134 133 135 136 + 0.00000 -0.00000 -0.00000 + 2 142 144 + 6 383 463 75 413 5 503 + + 0.33333 -9.66667 + 3 136 135 137 + 0.00000 -0.00000 -0.00000 + 2 142 268 + 5 5 463 75 503 303 + + 0.33333 -10.33333 + 3 137 135 138 + 0.00000 0.00000 -0.00000 + 3 194 235 268 + 6 5 463 303 503 145 231 + + 0.50000 -12.75000 + 4 138 135 139 140 + 0.00000 0.00000 -0.00000 + 1 194 + 5 5 463 145 231 47 + + -3.12500 -10.50000 + 4 137 138 142 141 + -0.00000 -0.00000 -0.00000 + 2 235 239 + 6 303 503 145 231 215 255 + + -6.50000 -10.33333 + 3 141 142 143 + -0.00000 -0.00000 -0.00000 + 3 10 62 239 + 6 215 303 145 255 50 403 + + -7.37500 -10.50000 + 4 143 142 145 144 + -0.00000 0.00000 -0.00000 + 1 10 + 5 145 255 50 403 6 + + -6.50000 -9.37500 + 4 141 143 147 146 + -0.00000 0.00000 -0.00000 + 2 62 98 + 6 215 303 50 403 506 4 + + -6.33333 -8.50000 + 3 146 147 148 + -0.00000 0.00000 -0.00000 + 3 80 98 175 + 6 215 506 4 403 26 370 + + -6.50000 -7.62500 + 4 148 147 150 149 + -0.00000 0.00000 -0.00000 + 1 80 + 5 4 403 26 370 246 + + -3.75000 -8.50000 + 4 146 148 152 151 + -0.00000 0.00000 -0.00000 + 2 175 280 + 6 215 506 26 370 216 288 + + -1.50000 -8.00000 + 4 153 151 152 154 + 0.00000 -0.00000 -0.00000 + 2 55 280 + 6 216 506 26 288 289 257 + + -0.25000 -7.50000 + 4 153 154 156 155 + -0.00000 -0.00000 -0.00000 + 1 55 + 5 216 289 257 288 410 + + 18.12500 -23.50000 + 4 91 90 157 158 + 0.00000 -0.00000 -0.00000 + 2 61 64 + 6 141 151 63 408 292 34 + + 23.50000 -22.00000 + 4 158 157 159 160 + -0.00000 -0.00000 -0.00000 + 2 61 296 + 6 141 292 34 408 175 40 + + 18.75000 -20.50000 + 4 160 159 161 162 + -0.00000 -0.00000 -0.00000 + 1 296 + 5 175 292 34 40 337 + + -19.37500 -5.50000 + 4 112 118 164 163 + -0.00000 -0.00000 -0.00000 + 2 174 185 + 6 449 510 152 352 344 446 + + -18.50000 -5.33333 + 3 163 164 165 + 0.00000 0.00000 -0.00000 + 3 171 174 297 + 6 344 510 152 446 265 534 + + -17.50000 -5.50000 + 4 163 165 167 166 + -0.00000 -0.00000 -0.00000 + 2 202 297 + 6 344 510 265 534 453 369 + + -16.50000 -5.33333 + 3 166 167 168 + -0.00000 -0.00000 -0.00000 + 3 59 101 202 + 6 344 453 265 369 2 322 + + -15.50000 -5.50000 + 4 166 168 170 169 + -0.00000 -0.00000 -0.00000 + 2 101 106 + 6 344 453 2 322 395 301 + + -14.50000 -5.33333 + 3 169 170 171 + 0.00000 0.00000 -0.00000 + 3 106 230 241 + 6 395 453 2 301 162 180 + + -11.50000 -5.50000 + 4 169 171 173 172 + 0.00000 0.00000 -0.00000 + 2 207 230 + 6 395 453 162 180 491 340 + + -8.50000 -5.33333 + 3 172 173 174 + -0.00000 -0.00000 -0.00000 + 3 110 126 207 + 6 395 491 162 340 48 124 + + -3.87500 -5.50000 + 4 172 174 176 175 + 0.00000 0.00000 -0.00000 + 2 126 282 + 6 395 491 48 124 123 445 + + -18.50000 -1.00000 + 4 165 164 177 178 + -0.00000 0.00000 -0.00000 + 1 171 + 5 152 446 265 534 119 + + -16.50000 -0.25000 + 4 168 167 179 180 + 0.00000 0.00000 -0.00000 + 2 59 218 + 6 265 369 2 322 41 290 + + -18.25000 4.50000 + 4 180 179 181 182 + 0.00000 -0.00000 -0.00000 + 1 218 + 5 41 369 290 322 144 + + -14.50000 0.75000 + 4 171 170 183 184 + 0.00000 -0.00000 -0.00000 + 2 108 241 + 6 2 301 162 180 378 133 + + -17.00000 6.50000 + 4 184 183 185 186 + -0.00000 -0.00000 -0.00000 + 2 90 108 + 6 301 378 133 180 363 366 + + -19.50000 9.00000 + 4 186 185 188 187 + 0.00000 0.00000 -0.00000 + 2 90 274 + 6 363 378 133 366 137 139 + + -15.00000 11.50000 + 4 187 188 190 189 + 0.00000 0.00000 -0.00000 + 2 96 274 + 6 137 366 139 363 347 85 + + -10.50000 12.25000 + 4 189 190 25 27 + -0.00000 0.00000 -0.00000 + 2 96 293 + 6 85 277 347 448 137 139 + + -8.62500 13.50000 + 4 27 26 192 191 + 0.00000 0.00000 -0.00000 + 1 303 + 5 429 500 347 448 371 + + -17.50000 14.50000 + 4 24 23 193 194 + 0.00000 -0.00000 -0.00000 + 2 54 190 + 6 179 332 434 500 23 120 + + -17.50000 15.33333 + 3 194 193 195 + 0.00000 0.00000 -0.00000 + 3 0 83 190 + 6 23 179 120 434 494 527 + + -20.62500 15.50000 + 4 195 193 196 197 + 0.00000 0.00000 -0.00000 + 2 0 266 + 6 23 179 494 527 308 428 + + -23.50000 17.00000 + 4 197 196 199 198 + -0.00000 0.00000 -0.00000 + 2 154 266 + 6 23 308 428 527 386 192 + + -22.75000 18.50000 + 4 198 199 201 200 + 0.00000 0.00000 -0.00000 + 2 154 244 + 6 386 428 192 308 98 138 + + -21.50000 18.50000 + 4 200 201 203 202 + 0.00000 -0.00000 -0.00000 + 4 122 165 173 244 + 8 98 386 138 192 13 247 115 481 + + -20.25000 18.50000 + 4 202 203 205 204 + 0.00000 0.00000 -0.00000 + 2 165 248 + 6 13 247 115 481 234 49 + + -21.50000 17.50000 + 4 200 202 208 207 + -0.00000 0.00000 -0.00000 + 1 122 + 5 98 386 13 247 169 + + -19.50000 18.00000 + 4 206 209 204 205 + 0.00000 -0.00000 -0.00000 + 2 23 248 + 6 13 234 49 481 157 195 + + -17.50000 17.50000 + 4 209 206 210 211 + 0.00000 0.00000 -0.00000 + 2 23 209 + 6 49 157 195 234 480 495 + + -15.50000 18.25000 + 4 211 210 212 213 + -0.00000 0.00000 -0.00000 + 2 209 210 + 6 157 480 195 495 339 365 + + -15.50000 19.33333 + 3 213 212 214 + -0.00000 0.00000 -0.00000 + 3 66 148 210 + 6 339 480 365 495 389 414 + + -16.62500 19.50000 + 4 214 212 215 216 + 0.00000 0.00000 -0.00000 + 2 148 261 + 6 339 480 389 414 226 171 + + -17.50000 20.25000 + 4 216 215 218 217 + -0.00000 0.00000 -0.00000 + 1 261 + 5 226 339 171 414 405 + + -21.50000 19.75000 + 4 203 201 219 220 + 0.00000 0.00000 -0.00000 + 2 124 173 + 6 138 192 115 481 250 121 + + -20.50000 20.50000 + 4 220 219 222 221 + -0.00000 -0.00000 -0.00000 + 2 124 301 + 6 138 250 115 121 170 30 + + -19.50000 21.25000 + 4 221 222 223 224 + 0.00000 -0.00000 -0.00000 + 2 166 301 + 6 121 170 30 250 335 125 + + -19.50000 22.33333 + 3 224 223 225 + -0.00000 0.00000 -0.00000 + 3 166 278 291 + 6 30 335 125 170 465 482 + + -21.37500 22.50000 + 4 225 223 226 227 + -0.00000 -0.00000 -0.00000 + 2 49 291 + 6 30 335 465 482 442 262 + + -23.33333 22.50000 + 3 227 226 228 + -0.00000 0.00000 -0.00000 + 3 49 138 184 + 6 335 442 262 482 240 367 + + -23.50000 23.37500 + 4 227 228 230 229 + 0.00000 0.00000 -0.00000 + 1 184 + 5 262 482 240 367 159 + + -23.50000 21.12500 + 4 228 226 231 232 + 0.00000 0.00000 -0.00000 + 1 138 + 5 335 442 240 367 377 + + -18.37500 22.49783 + 4 224 225 234 233 + 0.00000 0.00000 -0.00000 + 2 216 278 + 6 125 170 465 482 39 447 + + -17.50000 22.99783 + 4 235 233 234 236 + 0.00000 0.00000 -0.00000 + 2 216 249 + 6 39 125 447 465 156 224 + + -13.37500 19.50000 + 4 213 214 239 238 + -0.00000 -0.00000 -0.00000 + 2 66 164 + 6 365 495 389 414 522 424 + + -11.50000 20.50000 + 4 238 239 240 241 + -0.00000 -0.00000 -0.00000 + 2 109 164 + 6 365 522 389 424 110 33 + + -13.75000 21.50000 + 4 241 240 242 243 + 0.00000 0.00000 -0.00000 + 1 109 + 5 110 424 33 522 272 + + -15.50000 15.50000 + 4 194 195 245 244 + 0.00000 0.00000 -0.00000 + 2 83 159 + 6 120 434 494 527 108 490 + + -13.50000 15.66667 + 3 244 245 246 + -0.00000 -0.00000 -0.00000 + 3 26 95 159 + 6 108 120 490 494 221 298 + + -9.62500 15.50000 + 4 244 246 248 247 + 0.00000 0.00000 -0.00000 + 1 95 + 5 108 120 221 298 11 + + -13.50000 16.75000 + 4 246 245 249 250 + -0.00000 0.00000 -0.00000 + 2 26 227 + 6 490 494 221 298 36 264 + + -11.62500 17.50000 + 4 250 249 252 251 + 0.00000 0.00000 -0.00000 + 2 92 227 + 6 36 490 221 264 190 300 + + -9.50000 17.66666 + 3 251 252 253 + -0.00000 0.00000 -0.00000 + 3 92 219 229 + 6 190 264 36 300 27 91 + + -7.12500 17.50000 + 4 251 253 255 254 + 0.00000 -0.00000 -0.00000 + 1 219 + 5 190 264 27 91 486 + + -9.50000 20.75000 + 4 253 252 237 256 + 0.00000 0.00000 -0.00000 + 2 179 229 + 6 183 300 36 27 91 412 + + -4.50000 23.50000 + 4 256 237 258 257 + -0.00000 -0.00000 -0.00000 + 2 146 179 + 6 183 300 91 412 468 83 + + 0.50000 22.62500 + 4 257 258 260 259 + 0.00000 -0.00000 -0.00000 + 2 146 205 + 6 412 468 83 183 390 219 + + 0.33333 21.50000 + 3 259 260 261 + 0.00000 -0.00000 -0.00000 + 3 58 162 205 + 6 390 468 83 219 323 497 + + 0.50000 20.12500 + 4 261 260 263 262 + -0.00000 0.00000 -0.00000 + 1 162 + 5 83 219 323 497 45 + + -0.75000 21.50000 + 4 259 261 265 264 + -0.00000 -0.00000 -0.00000 + 2 58 253 + 6 390 468 323 497 212 528 + + -1.50000 19.50000 + 4 264 265 266 267 + -0.00000 0.00000 -0.00000 + 2 143 253 + 6 212 390 497 528 373 43 + + 1.00000 17.50000 + 4 267 266 268 269 + 0.00000 -0.00000 -0.00000 + 2 143 192 + 6 373 528 43 212 385 213 + + 3.50000 14.00000 + 4 269 268 271 270 + -0.00000 0.00000 -0.00000 + 2 91 192 + 6 373 385 43 213 276 244 + + 1.00000 10.50000 + 4 270 271 273 272 + 0.00000 0.00000 -0.00000 + 2 91 125 + 6 213 276 244 385 25 129 + + -1.50000 8.75000 + 4 272 273 274 275 + 0.00000 0.00000 -0.00000 + 2 125 283 + 6 25 276 129 244 243 181 + + -1.50000 6.66667 + 3 275 274 276 + -0.00000 0.00000 -0.00000 + 3 75 221 283 + 6 129 243 25 181 228 466 + + -5.12500 6.50000 + 4 275 276 278 277 + -0.00000 0.00000 -0.00000 + 2 75 189 + 6 25 181 228 466 285 287 + + -8.50000 5.62500 + 4 277 278 279 280 + 0.00000 -0.00000 -0.00000 + 2 128 189 + 6 181 285 228 287 94 12 + + -8.33333 4.50000 + 3 280 279 281 + -0.00000 -0.00000 -0.00000 + 3 128 252 272 + 6 94 287 12 285 14 399 + + -8.50000 2.37500 + 4 280 281 282 283 + 0.00000 -0.00000 -0.00000 + 2 157 272 + 6 12 285 14 399 270 376 + + -7.50000 0.50000 + 4 283 282 284 285 + -0.00000 0.00000 -0.00000 + 2 157 250 + 6 14 270 12 376 533 136 + + -5.25000 4.50000 + 4 281 279 286 287 + -0.00000 -0.00000 -0.00000 + 2 252 259 + 6 94 287 14 399 319 299 + + -2.50000 2.50000 + 4 287 286 289 288 + 0.00000 -0.00000 -0.00000 + 2 136 259 + 6 94 319 299 399 387 433 + + -3.50000 0.50000 + 4 288 289 291 290 + 0.00000 -0.00000 -0.00000 + 2 136 263 + 6 299 387 319 433 55 60 + + -6.50000 1.75000 + 4 285 284 292 293 + -0.00000 0.00000 -0.00000 + 1 250 + 5 270 533 136 376 1 + + -4.50000 1.75000 + 4 290 291 295 294 + -0.00000 0.00000 -0.00000 + 1 263 + 5 55 387 60 433 336 + + 1.12500 6.50000 + 4 276 274 296 297 + -0.00000 0.00000 -0.00000 + 2 181 221 + 6 129 243 228 466 484 70 + + 3.50000 4.62500 + 4 297 296 299 298 + -0.00000 0.00000 -0.00000 + 2 181 208 + 6 243 484 70 466 241 252 + + 3.66667 2.50000 + 3 298 299 300 + -0.00000 0.00000 -0.00000 + 3 65 208 281 + 6 70 241 252 484 64 324 + + 3.50000 1.62500 + 4 298 300 302 301 + -0.00000 0.00000 -0.00000 + 2 281 288 + 6 70 241 64 324 305 489 + + 3.50000 0.66667 + 3 301 302 303 + 0.00000 -0.00000 -0.00000 + 3 127 264 288 + 6 241 305 324 489 260 519 + + 4.87500 0.50000 + 4 303 302 304 305 + -0.00000 -0.00000 -0.00000 + 1 264 + 5 324 489 260 519 193 + + 2.37500 0.50000 + 4 301 303 307 306 + -0.00000 -0.00000 -0.00000 + 2 127 199 + 6 241 305 260 519 508 31 + + 1.50000 2.50000 + 4 306 307 309 308 + 0.00000 -0.00000 -0.00000 + 2 53 199 + 6 305 508 31 260 191 341 + + 0.50000 4.50000 + 4 308 309 310 311 + -0.00000 0.00000 -0.00000 + 2 53 271 + 6 191 508 31 341 196 147 + + -0.50000 1.75000 + 4 311 310 312 313 + -0.00000 0.00000 -0.00000 + 2 100 271 + 6 196 341 147 191 8 271 + + -0.50000 -1.33333 + 3 313 312 314 + 0.00000 0.00000 -0.00000 + 3 42 100 234 + 6 8 196 147 271 359 456 + + -1.37500 -1.50000 + 4 313 314 316 315 + -0.00000 -0.00000 -0.00000 + 1 42 + 5 147 271 359 456 54 + + 4.12500 -1.50000 + 4 314 312 317 318 + -0.00000 -0.00000 -0.00000 + 2 234 275 + 6 8 196 359 456 78 173 + + 8.50000 -2.50000 + 4 318 317 320 319 + 0.00000 0.00000 -0.00000 + 2 145 275 + 6 8 78 173 359 113 427 + + 5.50000 -3.50000 + 4 319 320 322 321 + 0.00000 0.00000 -0.00000 + 2 145 150 + 6 113 173 78 427 106 306 + + 2.50000 -5.50000 + 4 321 322 323 324 + -0.00000 0.00000 -0.00000 + 2 22 150 + 6 106 113 306 427 354 421 + + 4.00000 -7.50000 + 4 324 323 325 326 + -0.00000 0.00000 -0.00000 + 2 22 25 + 6 306 354 106 421 62 107 + + 5.50000 -11.00000 + 4 326 325 328 327 + 0.00000 -0.00000 -0.00000 + 2 18 25 + 6 62 354 107 421 267 35 + + 10.00000 -14.50000 + 4 327 328 329 330 + -0.00000 -0.00000 -0.00000 + 2 18 38 + 6 107 267 35 62 172 368 + + 14.50000 -15.37500 + 4 330 329 332 331 + -0.00000 0.00000 -0.00000 + 2 38 254 + 6 35 172 267 368 261 430 + + 14.66666 -16.50000 + 3 331 332 333 + -0.00000 0.00000 -0.00000 + 3 4 224 254 + 6 261 368 172 430 315 416 + + 14.50000 -17.62500 + 4 331 333 335 334 + -0.00000 -0.00000 -0.00000 + 2 121 224 + 6 261 368 315 416 214 100 + + 15.62500 -16.50000 + 4 333 332 336 337 + -0.00000 -0.00000 -0.00000 + 2 4 36 + 6 172 430 315 416 439 223 + + 16.50000 -16.33333 + 3 337 336 338 + 0.00000 -0.00000 -0.00000 + 3 36 197 284 + 6 430 439 223 315 256 521 + + 19.12500 -16.50000 + 4 337 338 339 340 + -0.00000 0.00000 -0.00000 + 2 211 284 + 6 223 315 256 521 266 426 + + 21.50000 -15.50000 + 4 340 339 341 342 + -0.00000 -0.00000 -0.00000 + 2 211 223 + 6 256 266 223 426 268 375 + + 19.00000 -14.50000 + 4 342 341 343 344 + -0.00000 -0.00000 -0.00000 + 2 223 256 + 6 266 268 375 426 521 439 + + 16.50000 -15.25000 + 4 344 343 338 336 + 0.00000 0.00000 -0.00000 + 2 197 256 + 6 430 439 256 521 268 375 + + 19.00000 -18.50000 + 4 334 335 345 346 + -0.00000 -0.00000 -0.00000 + 2 52 121 + 6 214 261 100 416 177 470 + + 23.49999 -13.50000 + 4 346 345 347 348 + -0.00000 -0.00000 -0.00000 + 2 52 78 + 6 100 177 214 470 318 444 + + 22.49999 -8.50000 + 4 348 347 349 350 + 0.00000 0.00000 -0.00000 + 2 78 81 + 6 177 318 444 470 321 353 + + 21.50000 -10.50000 + 4 350 349 351 352 + 0.00000 -0.00000 -0.00000 + 2 51 81 + 6 318 321 353 444 135 263 + + 16.50000 -12.50002 + 4 352 351 354 353 + -0.00000 -0.00000 -0.00000 + 2 51 240 + 6 135 321 263 353 225 211 + + 11.49999 -10.62502 + 4 353 354 356 355 + 0.00000 0.00000 -0.00000 + 2 240 298 + 6 225 263 135 211 52 258 + + 11.33331 -8.50000 + 3 355 356 357 + 0.00000 -0.00000 -0.00000 + 3 2 135 298 + 6 52 225 211 258 187 312 + + 11.49998 -7.12500 + 4 355 357 359 358 + -0.00000 -0.00000 -0.00000 + 2 89 135 + 6 52 225 187 312 388 516 + + 11.49997 -5.50000 + 4 358 359 361 360 + -0.00000 0.00000 -0.00000 + 3 89 245 279 + 7 52 388 187 516 44 338 205 + + 15.74997 -5.49998 + 4 358 360 363 362 + 0.00000 0.00000 -0.00000 + 2 134 279 + 6 52 388 44 338 349 202 + + 19.49999 -7.99998 + 4 362 363 365 364 + -0.00000 -0.00000 -0.00000 + 2 73 134 + 6 349 388 44 202 364 525 + + 16.25000 -10.50001 + 4 364 365 367 366 + -0.00000 -0.00000 -0.00000 + 1 73 + 5 349 364 202 525 471 + + 10.49999 -8.50000 + 4 357 356 368 369 + -0.00000 -0.00000 -0.00000 + 2 2 286 + 6 211 258 187 312 28 351 + + 9.66666 -8.50001 + 3 369 368 370 + 0.00000 0.00000 -0.00000 + 3 161 198 286 + 6 28 258 312 351 208 464 + + 9.49998 -7.62500 + 4 369 370 372 371 + 0.00000 0.00000 -0.00000 + 1 198 + 5 312 351 208 464 357 + + 9.50000 -10.62500 + 4 370 368 373 374 + 0.00000 -0.00000 -0.00000 + 2 161 257 + 6 28 258 208 464 174 61 + + 8.50001 -12.50000 + 4 374 373 376 375 + -0.00000 -0.00000 -0.00000 + 2 225 257 + 6 28 174 61 208 203 242 + + 7.50000 -9.25000 + 4 375 376 378 377 + 0.00000 -0.00000 -0.00000 + 2 147 225 + 6 61 203 174 242 278 417 + + 7.49998 -5.66667 + 3 377 378 379 + 0.00000 -0.00000 -0.00000 + 3 105 147 217 + 6 203 278 242 417 15 437 + + 5.62499 -5.50002 + 4 379 378 380 381 + -0.00000 0.00000 -0.00000 + 1 105 + 5 242 417 15 437 515 + + 8.87499 -5.50000 + 4 377 379 383 382 + -0.00000 0.00000 -0.00000 + 2 63 217 + 6 203 278 15 437 516 404 + + 10.49999 -5.50000 + 4 382 383 361 359 + -0.00000 -0.00000 -0.00000 + 3 63 243 245 + 7 187 516 205 338 278 404 437 + + 10.49998 -2.50000 + 4 361 383 384 385 + -0.00000 -0.00000 -0.00000 + 2 28 243 + 6 205 338 404 437 438 295 + + 10.49998 0.33333 + 3 385 384 386 + -0.00000 -0.00000 -0.00000 + 3 28 79 93 + 6 404 438 205 295 130 217 + + 8.62499 0.50000 + 4 386 384 387 388 + 0.00000 0.00000 -0.00000 + 1 93 + 5 404 438 130 217 148 + + 11.49999 0.50000 + 4 385 386 390 389 + 0.00000 0.00000 -0.00000 + 2 56 79 + 6 205 295 130 217 443 0 + + 12.50000 0.33333 + 3 389 390 391 + -0.00000 -0.00000 -0.00000 + 3 41 56 247 + 6 295 443 0 130 345 384 + + 16.12500 0.50000 + 4 391 390 393 392 + 0.00000 0.00000 -0.00000 + 2 70 247 + 6 0 130 345 384 407 325 + + 19.50000 -0.50000 + 4 392 393 395 394 + 0.00000 0.00000 -0.00000 + 2 19 70 + 6 345 407 0 325 512 82 + + 16.75000 -1.50000 + 4 394 395 397 396 + -0.00000 0.00000 -0.00000 + 1 19 + 5 407 512 82 325 391 + + 12.50000 -1.75000 + 4 389 391 399 398 + -0.00000 0.00000 -0.00000 + 2 41 222 + 6 295 443 345 384 396 76 + + 16.75000 -3.50000 + 4 398 399 400 401 + -0.00000 -0.00000 -0.00000 + 2 99 222 + 6 396 443 76 384 382 454 + + 21.33333 -3.50000 + 3 401 400 402 + 0.00000 -0.00000 -0.00000 + 3 20 99 176 + 6 76 382 396 454 17 381 + + 21.50000 -5.12500 + 4 401 402 404 403 + -0.00000 -0.00000 -0.00000 + 2 176 287 + 6 396 454 17 381 282 348 + + 22.75000 -6.50000 + 4 403 404 405 406 + 0.00000 0.00000 -0.00000 + 1 287 + 5 282 454 17 348 230 + + 21.49999 -0.50000 + 4 402 400 407 408 + -0.00000 -0.00000 -0.00000 + 2 20 236 + 6 76 382 17 381 89 186 + + 21.33333 2.50000 + 3 408 407 409 + -0.00000 0.00000 -0.00000 + 3 236 251 258 + 6 89 382 186 381 188 355 + + 21.49999 3.62500 + 4 408 409 410 411 + 0.00000 -0.00000 -0.00000 + 2 238 258 + 6 186 381 188 355 53 155 + + 16.24999 2.50000 + 4 409 407 412 413 + -0.00000 0.00000 -0.00000 + 2 5 251 + 6 89 382 188 355 329 90 + + 11.49999 5.25000 + 4 413 412 415 414 + -0.00000 0.00000 -0.00000 + 1 5 + 5 89 329 90 355 117 + + 17.49999 4.50000 + 4 411 410 416 417 + 0.00000 0.00000 -0.00000 + 2 238 246 + 6 53 188 155 186 487 254 + + 13.50000 8.50000 + 4 417 416 419 418 + -0.00000 0.00000 -0.00000 + 2 34 246 + 6 53 487 155 254 46 16 + + 11.50000 12.50000 + 4 418 419 420 421 + 0.00000 -0.00000 -0.00000 + 2 34 232 + 6 46 254 16 487 194 197 + + 9.50000 14.50000 + 4 421 420 423 422 + -0.00000 0.00000 -0.00000 + 2 232 269 + 6 16 194 46 197 380 441 + + 15.37500 16.50000 + 4 422 423 425 424 + -0.00000 0.00000 -0.00000 + 2 191 269 + 6 197 380 194 441 69 153 + + 21.50000 16.66666 + 3 424 425 426 + 0.00000 -0.00000 -0.00000 + 3 137 178 191 + 6 69 380 153 441 314 431 + + 22.62500 16.50000 + 4 424 426 428 427 + -0.00000 -0.00000 -0.00000 + 2 137 304 + 6 69 380 314 431 71 458 + + 23.50000 12.50000 + 4 427 428 430 429 + -0.00000 0.00000 -0.00000 + 2 255 304 + 6 69 71 314 458 101 134 + + 22.12500 8.50000 + 4 429 430 432 431 + -0.00000 0.00000 -0.00000 + 2 255 289 + 6 71 101 134 458 146 457 + + 20.50000 8.33333 + 3 431 432 433 + -0.00000 -0.00000 -0.00000 + 3 46 82 289 + 6 101 146 134 457 73 498 + + 18.87500 8.50000 + 4 431 433 435 434 + -0.00000 0.00000 -0.00000 + 2 82 129 + 6 101 146 73 498 248 297 + + 17.50000 11.25000 + 4 434 435 437 436 + 0.00000 -0.00000 -0.00000 + 2 129 160 + 6 146 248 297 498 317 313 + + 17.50000 14.33333 + 3 436 437 438 + 0.00000 0.00000 -0.00000 + 3 113 160 183 + 6 248 317 297 313 57 131 + + 14.12500 14.50000 + 4 438 437 439 440 + 0.00000 0.00000 -0.00000 + 1 183 + 5 297 313 57 131 275 + + 19.62500 14.50000 + 4 436 438 442 441 + -0.00000 0.00000 -0.00000 + 2 113 158 + 6 248 317 57 131 485 164 + + 21.50000 12.50000 + 4 441 442 444 443 + -0.00000 0.00000 -0.00000 + 2 131 158 + 6 317 485 57 164 409 502 + + 20.50000 10.50000 + 4 443 444 446 445 + 0.00000 -0.00000 -0.00000 + 2 32 131 + 6 409 485 164 502 77 29 + + 19.50000 11.75000 + 4 445 446 448 447 + -0.00000 0.00000 -0.00000 + 1 32 + 5 77 409 29 502 93 + + 20.50000 7.50000 + 4 433 432 449 450 + 0.00000 -0.00000 -0.00000 + 2 46 302 + 6 134 457 73 498 103 394 + + 20.50000 6.66667 + 3 450 449 451 + 0.00000 0.00001 -0.00009 + 3 163 196 302 + 6 103 457 73 394 24 505 + + 17.87500 6.50000 + 4 450 451 453 452 + 0.00002 0.00001 -0.00055 + 2 193 196 + 6 73 394 24 505 279 220 + + 15.50000 9.75000 + 4 452 453 455 454 + 0.00000 0.00002 -0.00029 + 1 193 + 5 279 394 220 505 291 + + 22.12500 6.50000 + 4 451 449 2 456 + 0.00000 0.00000 -0.00008 + 2 7 163 + 6 103 472 457 24 505 206 + + 23.50000 0.75000 + 4 456 2 458 457 + -0.00000 0.00000 -0.00000 + 1 7 + 5 103 472 24 206 165 + + 21.50000 17.50000 + 4 426 425 459 460 + -0.00000 -0.00000 -0.00000 + 2 172 178 + 6 153 441 314 431 476 358 + + 21.50000 18.33333 + 3 460 459 461 + 0.00000 0.00000 -0.00000 + 3 21 102 172 + 6 153 476 358 431 21 320 + + 22.62500 18.50000 + 4 460 461 463 462 + -0.00000 0.00000 -0.00000 + 2 16 102 + 6 358 431 21 320 286 105 + + 23.50000 19.37500 + 4 462 463 464 465 + -0.00000 0.00000 -0.00000 + 2 16 67 + 6 286 358 21 105 309 356 + + 23.33333 20.50000 + 3 465 464 466 + 0.00000 0.00000 -0.00000 + 3 47 67 294 + 6 105 309 286 356 104 350 + + 23.50000 22.00000 + 4 465 466 467 468 + -0.00000 0.00000 -0.00000 + 2 169 294 + 6 286 356 104 350 42 74 + + 23.33333 23.50000 + 3 468 467 469 + 0.00000 0.00000 -0.00000 + 3 24 123 169 + 6 42 350 74 356 168 280 + + 23.49737 24.37500 + 4 468 469 470 471 + -0.00000 0.00000 -0.00000 + 2 40 123 + 6 74 356 168 280 210 361 + + 23.49474 25.40630 + 4 471 470 472 473 + 0.00000 -0.00000 -0.00000 + 2 40 72 + 6 168 210 74 361 222 316 + + 23.49474 29.70447 + 4 473 472 474 475 + -0.00000 0.00000 -0.00000 + 1 72 + 5 210 222 316 361 189 + + 12.75000 23.50000 + 4 469 467 476 477 + -0.00000 0.00000 -0.00000 + 2 24 267 + 6 42 350 168 280 96 176 + + 2.50000 21.50000 + 4 477 476 478 479 + -0.00000 -0.00000 0.00000 + 2 112 267 + 6 42 96 176 280 499 218 + + 3.87500 19.50000 + 4 479 478 480 481 + 0.00000 0.00000 0.00000 + 2 112 212 + 6 96 499 176 218 274 150 + + 5.50000 19.33333 + 3 481 480 482 + 0.00000 0.00000 -0.00000 + 3 212 215 273 + 6 274 499 150 218 128 327 + + 6.50000 19.50000 + 4 482 480 483 484 + 0.00000 0.00000 0.00000 + 2 30 215 + 6 274 499 128 327 296 7 + + 7.50000 19.33333 + 3 484 483 485 + 0.00000 0.00000 -0.00000 + 3 30 115 195 + 6 274 296 7 327 10 517 + + 9.62500 19.50000 + 4 485 483 486 487 + 0.00000 0.00000 0.00000 + 2 195 285 + 6 274 296 10 517 235 140 + + 11.50000 18.75000 + 4 487 486 489 488 + 0.00000 0.00000 0.00000 + 1 285 + 5 235 296 140 517 118 + + 19.00000 20.50000 + 4 466 464 490 491 + -0.00000 0.00000 -0.00000 + 1 47 + 5 105 309 104 350 474 + + 17.37500 18.50000 + 4 461 459 492 493 + -0.00000 0.00000 -0.00000 + 2 21 295 + 6 153 476 21 320 199 342 + + 13.50000 20.00000 + 4 493 492 495 494 + -0.00000 0.00000 -0.00000 + 2 86 295 + 6 199 476 320 342 238 198 + + 8.75000 21.50000 + 4 494 495 496 497 + 0.00000 0.00000 -0.00000 + 1 86 + 5 238 342 198 199 251 + + 6.75000 2.50000 + 4 300 299 498 499 + -0.00000 -0.00000 -0.00000 + 2 65 214 + 6 252 484 64 324 32 59 + + 9.50000 3.37500 + 4 499 498 500 501 + -0.00000 0.00000 -0.00000 + 2 120 214 + 6 32 252 59 64 507 249 + + 9.33333 4.50000 + 3 501 500 502 + 0.00000 0.00000 -0.00000 + 3 12 84 120 + 6 32 507 59 249 114 167 + + 9.50000 5.62500 + 4 501 502 503 504 + -0.00000 0.00000 -0.00000 + 2 11 12 + 6 59 249 114 167 283 163 + + 7.50000 6.50000 + 4 504 503 505 506 + 0.00000 0.00000 -0.00000 + 2 11 220 + 6 167 283 163 249 112 22 + + 5.50000 5.25000 + 4 506 505 507 508 + 0.00000 0.00000 -0.00000 + 1 220 + 5 112 283 22 163 253 + + 8.00000 4.50000 + 4 502 500 509 510 + 0.00000 0.00000 -0.00000 + 1 84 + 5 32 507 114 167 343 + + -8.50000 -3.25000 + 4 174 173 511 512 + 0.00000 0.00000 -0.00000 + 2 110 265 + 6 162 340 48 124 398 535 + + -6.00000 -1.50000 + 4 512 511 514 513 + -0.00000 0.00000 -0.00000 + 2 231 265 + 6 340 398 124 535 116 346 + + -3.50000 -2.25000 + 4 513 514 516 515 + -0.00000 0.00000 -0.00000 + 2 29 231 + 6 116 535 346 398 19 469 + + -3.50000 -3.33333 + 3 515 516 517 + 0.00000 -0.00000 -0.00000 + 3 29 97 177 + 6 19 116 346 469 56 304 + + -5.37500 -3.50000 + 4 515 517 519 518 + -0.00000 0.00000 -0.00000 + 1 97 + 5 19 116 56 304 302 + + -1.37500 -3.50000 + 4 517 516 520 521 + 0.00000 -0.00000 -0.00000 + 2 50 177 + 6 346 469 56 304 123 445 + + 0.50000 -4.50000 + 4 521 520 175 176 + -0.00000 -0.00000 -0.00000 + 2 50 282 + 6 123 491 48 445 469 56 + + 7.50000 14.75000 + 4 484 485 523 522 + 0.00000 0.00000 0.00000 + 2 68 115 + 6 7 327 10 517 132 530 + + 9.50000 10.50000 + 4 522 523 524 525 + 0.00000 0.00000 0.00000 + 2 68 306 + 6 7 132 10 530 245 80 + + 11.50000 9.75000 + 4 525 524 527 526 + 0.00000 0.00000 0.00000 + 1 306 + 5 245 530 80 132 161 + + 5.50000 14.00000 + 4 481 482 529 528 + 0.00000 0.00000 0.00000 + 2 182 273 + 6 150 218 128 327 360 451 + + 5.50000 8.66667 + 3 528 529 530 + 0.00000 0.00000 0.00000 + 3 44 57 182 + 6 150 360 128 451 127 401 + + 7.87500 8.50000 + 4 530 529 531 532 + 0.00000 0.00000 0.00000 + 1 44 + 5 128 451 127 401 440 + + 2.62500 8.50000 + 4 528 530 534 533 + 0.00000 0.00000 0.00000 + 1 57 + 5 150 360 127 401 109 + + -14.25000 23.50000 + 4 235 236 536 535 + 0.00000 0.00000 -0.00000 + 1 249 + 5 39 156 224 447 142 diff --git a/examples/core/maze/mazeField.txt b/examples/core/maze/mazeField.txt new file mode 100644 index 00000000..9727f963 --- /dev/null +++ b/examples/core/maze/mazeField.txt @@ -0,0 +1,2503 @@ +50 50 +1.0 +-25.0 -25.0 +1.0 0.0 +1.0 1.00908282548e-05 +1.0 1.37300744996e-07 +1.0 8.05230286005e-07 +1.0 1.00638671008e-10 +1.0 -2.98209783978e-07 +1.0 4.17747423853e-06 +1.0 2.72265901913e-06 +1.0 2.12883674067e-06 +1.0 2.33612695411e-06 +1.0 3.06412721329e-06 +1.0 2.20961328523e-06 +1.0 2.1422122245e-06 +1.0 -7.78829473802e-07 +1.0 3.34838290428e-07 +1.0 3.12077986564e-07 +1.0 3.34499702603e-07 +1.0 7.98211260644e-07 +1.0 6.38732046809e-07 +1.0 4.28706840694e-07 +1.0 2.60754461578e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 5.36699706899e-09 +1.0 4.2415167627e-06 +1.0 2.78735069514e-06 +1.0 2.48432343142e-06 +1.0 2.06061758945e-06 +1.0 1.60393403803e-06 +1.0 1.91149547391e-06 +1.0 2.03707259061e-06 +1.0 1.67695156961e-06 +1.0 6.63154060021e-06 +0.999999880791 -0.000514809275046 +0.999992787838 -0.00370436324738 +1.0 -3.30947846905e-09 +1.0 0.0 +0.629066586494 0.77735131979 +8.46046968945e-05 1.0 +-0.721230149269 0.692695319653 +0.999999165535 0.000280125997961 +0.993519604206 -0.113660492003 +0.998685061932 -0.0512655228376 +-2.54352780757e-05 0.999999582767 +-0.999961972237 0.00866464618593 +-0.999989032745 0.00466264691204 +-0.999999463558 0.000652225513477 +-0.999969601631 0.00774748204276 +-0.999925553799 -0.0121934628114 +-0.999305605888 -0.0372572019696 +-1.0 4.65756820631e-05 +-1.0 6.30934955552e-05 +-0.999999821186 6.61929298076e-05 +-1.0 -1.04109687982e-06 +-0.999999761581 -8.02676936473e-07 +-0.999999821186 -1.51793290115e-06 +-0.999999284744 -1.4630944861e-05 +1.0 1.02096393562e-07 +0.999846041203 -0.0175223592669 +1.0 -3.24268585246e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -6.80413547727e-09 +0.999999463558 -0.000258041283814 +1.0 4.14298872986e-10 +0.0970246493816 0.995281934738 +-0.999999880791 0.000144871053635 +-0.999994933605 0.00311174569651 +-0.99998575449 0.00528848636895 +-0.999957084656 0.00926448497921 +-0.999748647213 0.0224136710167 +-0.999918937683 0.0127253970131 +-0.999861478806 0.0166386142373 +-0.999493300915 0.0318260006607 +-0.999998509884 0.00137764366809 +-0.999999523163 6.27832832834e-07 +-0.99930614233 0.037217259407 +1.0 5.78348497982e-08 +1.0 0.0 +0.817331552505 0.576167464256 +0.00661921640858 0.999977827072 +-0.547625362873 0.836723089218 +1.0 -6.15072224264e-08 +6.98963549439e-06 -0.999999880791 +1.0 -7.27797610047e-14 +0.00129432987887 0.99999910593 +1.0 1.02410717773e-06 +1.0 8.9784633019e-05 +1.0 3.87549050629e-07 +1.0 4.68344779847e-07 +1.0 5.51500022539e-07 +1.0 4.89142564675e-07 +1.0 5.01645615714e-07 +1.0 5.06740036599e-07 +1.0 5.19451532455e-07 +1.0 5.93311654029e-07 +1.0 5.3004231404e-07 +1.0 -8.89937000466e-05 +-1.78866002898e-06 -0.999999046326 +1.0 3.75480489799e-13 +0.0303495526314 -0.999539256096 +1.0 -1.90944101632e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 7.34958885005e-05 +1.0 8.46885825356e-11 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -1.05146391149e-07 +3.17493936564e-06 -0.999999940395 +1.0 1.81957582335e-09 +-0.113657101989 0.993519961834 +1.0 4.28314592682e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.85535282071e-05 +0.256753504276 -0.966476500034 +1.0 -3.2531804095e-07 +1.0 0.0 +1.0 3.78746598528e-08 +-0.0197923742235 0.999803781509 +-0.943380534649 0.33171197772 +1.0 -4.52821851127e-08 +-0.0488994494081 -0.99880361557 +1.0 5.43040243883e-08 +-0.00990966614336 0.999950647354 +1.0 8.03809996341e-07 +0.000114754788228 0.999999880791 +-0.998375356197 0.0569798760116 +-0.999999463558 0.000754267442971 +-0.999999642372 0.00067678274354 +-0.999997377396 0.00226154900156 +-0.999996066093 0.00273313862272 +-0.999998629093 0.00155583035666 +-0.999999284744 0.00108209403697 +-0.999999880791 0.000195829052245 +-0.999999821186 0.000614923774265 +1.0 -1.06565903479e-05 +0.00043959976756 -0.999999046326 +1.0 0.0 +1.0 -6.6495758233e-08 +1.0 -2.9772698521e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.000174098851858 0.999999940395 +1.0 9.41855250858e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -7.67840262483e-08 +2.15331674553e-05 -0.999999940395 +1.0 6.68182664754e-08 +4.36699338024e-06 0.999999940395 +1.0 1.36675371021e-09 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.88421285606e-05 +1.38679047268e-06 -0.999999523163 +1.0 -2.98475157479e-07 +1.0 0.0 +1.0 1.57691999902e-07 +7.52693765094e-08 1.0 +1.0 5.10671441134e-07 +1.0 3.37670172712e-07 +1.0 2.86072094013e-07 +1.0 -2.3228363677e-10 +-0.000323458400089 0.999999821186 +1.0 3.86084906268e-07 +0.00014980234846 0.999999940395 +1.0 1.2039706121e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -6.95758217262e-06 +0.000494641077239 -0.999999880791 +1.0 -1.25041096908e-05 +1.89105503523e-05 -0.999999344349 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 6.27283839094e-07 +1.0 7.22802406036e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -3.21513857204e-11 +0.0328552424908 -0.999460041523 +1.0 7.21645037061e-08 +1.62521814673e-06 0.999999880791 +1.0 0.0 +1.0 -2.04667358048e-05 +0.999889492989 -0.0148668177426 +1.0 -2.3618897103e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.32225795319e-07 +8.18172702566e-06 -0.999999761581 +1.0 -3.36457532057e-07 +1.0 0.0 +1.0 1.47711034515e-07 +-4.37113705232e-08 0.999999761581 +-0.999999880791 3.89406551449e-07 +-0.999999940395 8.66251468779e-07 +-0.999999701977 0.000211389706237 +-0.999900519848 -0.0140698077157 +-0.998649477959 0.0519478730857 +1.0 4.94583673571e-06 +3.13083291985e-05 0.999999940395 +1.0 1.32730320956e-07 +0.999998569489 -0.00166482641362 +1.0 -7.38004442063e-19 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -3.66478502656e-07 +6.25399110277e-08 -0.999999940395 +1.0 -3.03158376482e-05 +-0.000963492086157 -0.999998569489 +1.0 1.14751333058e-06 +1.0 7.20103514595e-07 +1.0 4.71888739639e-07 +1.0 4.8229139793e-07 +1.0 8.4264047473e-07 +1.0 6.69938117426e-07 +1.0 6.43079715701e-07 +1.0 5.41626559425e-06 +1.0 5.26107214682e-06 +1.0 7.95548567112e-06 +1.0 5.05589980548e-07 +1.0 2.61343188868e-07 +1.0 3.2037766573e-07 +1.0 3.04809248064e-07 +1.0 2.05010621812e-07 +1.0 4.20469262963e-07 +7.54977449446e-08 1.0 +1.0 8.5747881167e-15 +1.0 -2.13995153899e-05 +1.0 -2.12725603888e-06 +1.0 -4.13566203505e-09 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.986282646656 -0.165064021945 +0.999999701977 2.12199211092e-07 +1.0 -5.81807410007e-18 +1.0 0.0 +1.0 1.40095906431e-07 +-1.05341287053e-05 1.0 +1.0 1.1765397403e-06 +1.0 9.81198468253e-07 +1.0 3.49559413735e-05 +0.999999701977 0.000304102082737 +1.0 0.000213778606849 +1.0 7.76849333306e-07 +2.86656700155e-07 1.0 +1.0 -1.63831458622e-07 +7.10580820851e-07 -0.999999761581 +1.0 -2.41537463808e-06 +1.0 5.04608528085e-14 +1.0 4.38802373992e-07 +1.0 2.84844986709e-07 +1.0 2.74001791922e-07 +1.0 3.23776191635e-07 +1.0 3.89989160965e-08 +1.0 -1.74681299541e-05 +-0.000886125315446 -0.999998629093 +-0.999999701977 2.86976028292e-05 +-0.999999821186 0.000492485240102 +-0.999926269054 0.0121274841949 +-0.99999833107 0.00183787813876 +-0.999999940395 3.19703417517e-06 +-0.999999701977 5.63462026548e-06 +-0.999999821186 6.27832207556e-07 +-0.999999761581 1.99397327378e-05 +-0.999999880791 -1.04109687982e-06 +-0.999999880791 -8.02678357559e-07 +-0.999999940395 7.06513355908e-06 +-0.999999940395 0.000210435959161 +-0.999999821186 0.000291479984298 +-0.999999880791 0.000336082681315 +-0.999999821186 0.000324638152961 +-0.999999523163 0.000855596561451 +-1.0 5.63460662306e-06 +1.0 5.39642854847e-08 +0.999999582767 -1.24055150081e-05 +1.0 -7.74176101004e-09 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 2.6852463634e-05 +0.000459507864434 0.999999463558 +1.0 0.0 +1.0 0.0 +1.0 6.26310850294e-07 +-1.62920656521e-07 0.999999880791 +-0.999998211861 0.000549228047021 +-0.999999701977 0.000721128599253 +-0.999999821186 0.000402362813475 +-1.0 8.24054004624e-05 +-0.999999821186 0.000382335827453 +-0.999768018723 0.0215344205499 +-0.99999922514 0.00120711291675 +1.0 1.32715847201e-08 +-0.00168828095775 -0.999996602535 +1.0 -2.03246941055e-06 +0.00214018579572 0.99999755621 +-0.999999821186 -6.26146245963e-09 +-1.0 2.29676288654e-06 +-0.999999880791 6.76314175507e-06 +-0.999999821186 3.67392112821e-06 +-0.999999940395 1.50995774106e-07 +1.0 -9.93158300844e-06 +0.0527416467667 -0.998607754707 +1.0 -1.05307584874e-07 +1.0 5.88639637034e-10 +1.0 7.14302814231e-07 +1.0 5.1213947927e-07 +1.0 2.59366942146e-07 +1.0 2.10034343695e-07 +1.0 2.79239998235e-07 +1.0 2.58886700522e-07 +1.0 2.83683903035e-07 +1.0 1.8749441324e-06 +1.0 1.35162849801e-06 +1.0 9.96235144157e-07 +1.0 9.53625601596e-07 +1.0 1.06723689441e-06 +1.0 1.1495291119e-06 +1.0 1.64736673014e-06 +1.0 1.05281492324e-06 +1.0 5.81901107161e-12 +1.75992627192e-05 -0.999999940395 +1.0 -8.07006586001e-07 +1.0 1.98028965315e-06 +1.0 1.44728574014e-06 +1.0 1.81977623015e-06 +1.0 1.51492520217e-06 +1.0 -3.01991519791e-07 +1.0 4.3878205247e-07 +1.0 3.25031578541e-05 +0.00023217589478 0.999999642372 +1.0 0.0 +1.0 0.0 +1.0 1.25122357986e-06 +7.54978799478e-08 0.999999821186 +1.0 1.32869558911e-06 +1.0 2.9607399199e-08 +1.0 0.0 +1.0 7.84480309489e-14 +1.0 0.000170921033714 +1.0 -3.09423256795e-07 +1.33632929646e-05 -0.999999940395 +1.0 3.44440463463e-15 +-4.3711310127e-08 -0.999998927116 +1.0 -5.06511514686e-06 +5.18123233633e-05 0.999999940395 +1.0 4.17928731622e-07 +1.0 6.02939098826e-06 +1.0 -1.91967428691e-05 +2.32910078921e-05 -0.999999403954 +1.0 -7.003231417e-07 +1.0 -8.66486573159e-07 +-1.10185237645e-05 -1.0 +1.0 -2.03058277748e-07 +-0.00791074335575 0.999968588352 +-0.999999940395 1.42978095141e-07 +-0.999999821186 1.50995589365e-07 +-0.999999761581 0.000709446205292 +-0.999996006489 0.00271191867068 +-0.999999880791 3.32911404257e-05 +-0.999999761581 0.000624447828159 +-1.0 0.000147668528371 +-0.999999701977 1.50995745685e-07 +-0.999999761581 8.66247887643e-07 +-0.999980032444 0.00631292071193 +-0.999990999699 0.00420415541157 +-0.999991834164 0.00402843719348 +-0.999996721745 0.0025037813466 +-0.999999701977 0.00026455684565 +-0.999992549419 0.0037604784593 +1.0 4.91501923534e-05 +-5.42371271877e-05 -0.999999880791 +-1.0 -1.62329092745e-06 +-0.999999940395 3.32865820383e-05 +-0.999998867512 0.00106653291732 +-0.999999940395 3.13838208967e-05 +-0.999999582767 -0.000447360507678 +-0.999963641167 -0.00851939339191 +-0.999999701977 -0.000147321115946 +1.0 1.10901983135e-05 +9.91216984403e-06 0.999999701977 +1.0 0.0 +1.0 0.0 +1.0 1.59395327159e-07 +-2.2533490629e-09 0.999999761581 +1.0 6.19884485786e-06 +0.00020904710982 0.999999761581 +1.0 0.0 +1.0 4.41971721443e-08 +-1.76522735273e-05 0.999999463558 +1.0 0.000144741105032 +0.00100918102544 -0.999999284744 +1.0 0.0 +-0.000232859194512 -0.999998986721 +1.0 -7.02262195773e-06 +3.88131446982e-08 0.999999821186 +1.0 8.87281714768e-07 +5.43991563973e-06 1.0 +1.0 -9.46743421082e-06 +7.32698608772e-05 -0.999999344349 +1.0 -7.61785940995e-07 +1.0 -7.992895803e-07 +7.54978657369e-08 -0.999999582767 +1.0 -2.04991408737e-07 +0.00151164829731 0.999998748302 +1.0 2.97008909911e-07 +1.0 3.73715354452e-13 +1.0 3.2479746892e-07 +1.0 3.75818227246e-15 +1.0 0.0 +-5.36347233293e-09 -0.999999940395 +1.0 -3.86554916076e-07 +1.0 -4.10724538824e-08 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -2.17844501549e-07 +4.88761145334e-07 -0.999999701977 +1.0 -8.27259555081e-07 +0.000110569228127 -0.999999821186 +1.0 -9.4974775493e-06 +1.0 0.0 +1.0 0.0 +1.0 -4.9503273658e-07 +7.70489168644e-06 -0.999999880791 +1.0 9.43680242926e-06 +0.0176036991179 0.999844670296 +1.0 0.0 +1.0 0.0 +1.0 8.30728907886e-08 +7.54978941586e-08 0.999999940395 +1.0 5.03927310547e-07 +0.0219544935971 0.999758780003 +1.0 3.03685854242e-10 +1.0 3.15007476738e-16 +-1.51168862317e-07 0.999999582767 +1.0 6.05610111961e-05 +0.00029213790549 -0.999999761581 +1.0 0.0 +3.65176720152e-06 -0.999999582767 +1.0 -8.03263174021e-06 +0.00522976089269 0.999986052513 +1.0 3.73098743012e-07 +4.48624132332e-06 1.0 +1.0 -7.01214366927e-06 +0.000568584422581 -0.999999582767 +1.0 -5.38615267942e-07 +1.0 -1.86286115422e-06 +-5.4081287999e-06 -0.999999940395 +1.0 -5.09288668127e-07 +0.000234321676544 0.999999701977 +1.0 4.62129293055e-07 +1.0 6.38832125333e-06 +6.75121737004e-06 0.999999880791 +1.0 1.16787795434e-07 +1.0 0.0 +-0.0508719608188 -0.998704850674 +1.0 -3.04589912048e-06 +0.999999940395 -2.89983201895e-08 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -9.39498576713e-08 +6.5127965172e-06 -0.999999642372 +1.0 -3.5191547795e-05 +-0.00187012541573 -0.999997913837 +-0.999999940395 0.000377504038624 +-0.999999046326 0.00122228369582 +-0.999996125698 0.00273790769279 +-0.999998688698 -0.00162177928723 +-0.999999403954 -1.47429872754e-07 +1.0 9.71255940385e-06 +0.0183777678758 0.999830901623 +1.0 0.0 +1.0 0.0 +1.0 7.89120235822e-08 +1.74441674972e-06 0.999999940395 +1.0 9.86019710325e-10 +5.67833376408e-06 0.999999880791 +1.0 1.81802377597e-07 +1.0 0.0 +6.71544000852e-07 0.999999523163 +1.0 3.29528556904e-05 +0.0889842286706 -0.996032834053 +1.0 0.0 +1.14837985166e-06 -0.999999701977 +1.0 -1.02171852632e-05 +6.15517046754e-06 0.999999880791 +1.0 4.89594015107e-07 +3.13916444838e-07 0.999999940395 +1.0 -4.00377803089e-06 +0.0460837520659 -0.998937249184 +1.0 -2.6714369028e-07 +1.0 -7.43170878569e-13 +1.0 -2.86396902993e-06 +1.0 -1.28256617566e-13 +-9.65445412504e-09 0.999999821186 +1.0 1.11628980903e-06 +1.0 4.62075973928e-07 +7.54978728423e-08 0.999999821186 +1.0 2.16600582803e-07 +1.0 0.0 +0.00279314466752 -0.999996066093 +1.0 -2.53127541328e-06 +4.21563745476e-05 -1.0 +1.0 0.0 +0.999999523163 0.000964545470197 +1.0 9.64345409082e-11 +1.0 0.0 +1.0 6.83341543208e-15 +1.0 2.63065516037e-07 +1.0 3.15364991366e-06 +1.0 3.21513630297e-06 +1.0 2.07921289075e-06 +1.0 2.65903304353e-06 +1.0 1.16104320114e-06 +1.0 3.81527843274e-06 +1.0 3.45488547282e-06 +1.0 2.93199013868e-06 +1.0 3.2422442473e-06 +1.0 1.17471574868e-06 +1.0 1.61534524068e-06 +4.72465944767e-06 0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 9.18752434131e-08 +7.54977875772e-08 1.0 +1.0 0.0 +0.000590994372033 0.999999761581 +1.0 2.48614753673e-07 +1.0 0.0 +-6.43939568334e-09 0.999999761581 +1.0 2.87975285573e-06 +1.0 -6.11522091276e-06 +1.0 0.0 +0.0910378545523 -0.995846807957 +1.0 -6.51220034342e-06 +6.95745111443e-05 1.0 +1.0 3.81749060807e-07 +3.29414820044e-06 0.999999940395 +1.0 -1.39564528823e-08 +9.52438767854e-06 -0.999999880791 +-0.999999821186 -5.13960207726e-10 +-0.999961853027 -0.00871679652482 +-1.0 9.62335834629e-05 +-1.0 0.000178249669261 +-0.999999940395 2.83708395727e-05 +1.0 2.32554612012e-06 +1.0 1.42524228863e-07 +-4.36407638915e-08 0.999999940395 +1.0 1.57850166715e-07 +1.0 0.0 +0.00113292085007 -0.99999922514 +1.0 -2.78392826658e-06 +8.66213958943e-05 -0.999999761581 +1.0 0.0 +2.91397952878e-07 0.999999523163 +1.0 2.13152793549e-06 +1.0 2.21785271037e-07 +1.0 1.54453914547e-07 +-0.0135639198124 0.999907493591 +-0.999999761581 7.86393286489e-07 +-0.999999821186 1.34308845645e-06 +-0.999999940395 0.000112922971311 +-0.999999940395 8.97246081877e-06 +-1.0 0.000129612279125 +-0.999999880791 2.53518123827e-06 +-0.999999821186 2.2967624318e-06 +-0.999999821186 4.68810285383e-05 +-0.999999761581 1.81992538728e-06 +-0.999005615711 -0.0445752069354 +1.0 1.54439840117e-06 +4.93089282827e-05 1.0 +1.0 0.0 +1.0 0.0 +1.0 9.30731971494e-08 +1.50600919824e-06 0.999999940395 +1.0 -1.82197240406e-07 +0.999996542931 -0.00251133460552 +0.999999523163 -1.13600447094e-06 +1.0 0.0 +1.0 7.0419343956e-07 +1.0 1.31954600783e-13 +1.0 0.0 +1.0 0.0 +-0.00365236913785 -0.999993145466 +1.0 -5.54724010726e-06 +0.0003472128883 0.999999821186 +1.0 3.38274645628e-07 +1.73608405021e-05 0.999999821186 +1.0 0.0 +1.0 -2.68617736765e-06 +1.0 4.23531361093e-07 +1.0 4.28288387866e-07 +1.0 4.39499245886e-07 +1.0 4.29371596056e-07 +1.0 4.00609991402e-07 +1.0 8.72387557159e-14 +1.0 1.86580464856e-07 +3.39527264259e-06 0.999999940395 +1.0 8.36102831414e-09 +1.0 0.0 +0.00593761354685 -0.999982178211 +1.0 -3.52880147148e-06 +1.94707126866e-07 -0.999999940395 +1.0 0.0 +5.81996282563e-05 0.999999880791 +1.0 3.74742876375e-06 +1.14571994345e-05 0.999999821186 +1.0 2.05810511034e-06 +2.34047388403e-06 0.999999821186 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.03390840802e-05 +1.0 0.000186950957868 +7.46730535184e-08 -0.999999940395 +1.0 4.87293846163e-07 +0.105279892683 0.994442462921 +1.0 0.0 +1.0 0.0 +1.0 1.30124888642e-07 +7.54977875772e-08 0.999999880791 +1.0 -3.14246648451e-13 +1.0 1.24205416796e-05 +1.0 -1.01709895262e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -8.01192243216e-07 +1.0 -7.11157369972e-13 +1.40864940477e-05 1.0 +1.0 4.63758794922e-07 +1.02917204003e-06 0.999999880791 +1.0 0.0 +1.0 0.0 +1.0 -4.72625373504e-07 +1.0 -5.56169558108e-14 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.59620685231e-07 +5.96755922455e-10 0.999999821186 +1.0 0.0 +1.0 0.0 +0.00036926654866 -0.999999940395 +1.0 -3.76888442588e-06 +0.00682487152517 -0.999976456165 +1.0 0.0 +0.00240845745429 0.999996721745 +1.0 2.43533213506e-06 +8.85286499397e-05 1.0 +1.0 1.67776113358e-06 +1.21156344903e-05 0.999999880791 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.0615228712559 0.998105168343 +1.0 0.000183915472007 +-4.37113634177e-08 -0.999999880791 +1.0 -1.61241061392e-07 +1.86363683952e-06 0.999999821186 +1.0 4.89790237244e-15 +1.0 0.0 +1.0 8.79511645735e-08 +7.34726336304e-06 0.999999940395 +0.999596059322 0.0284157786518 +-5.40812834515e-06 0.999999821186 +-0.999993681908 0.00311937183142 +-0.999998569489 0.00153198232874 +-0.999999403954 0.000651986862067 +-0.999999940395 -8.87790229172e-05 +-0.998449206352 -0.055668476969 +-0.999812662601 0.0193549506366 +-0.999921500683 0.0125086875632 +-0.999996483326 0.00260892370716 +-0.999954164028 0.0095541505143 +1.0 5.39582424608e-06 +0.000519589520991 0.999999880791 +1.0 2.85801451949e-11 +1.0 0.0 +4.76592845189e-07 -0.999999880791 +1.0 -1.49279219386e-06 +1.0 1.56397527462e-06 +1.0 5.90065099004e-07 +1.0 5.47909849047e-07 +1.0 5.69639666992e-07 +1.0 2.44002734684e-13 +1.0 9.65719024748e-08 +1.0 0.0 +1.0 0.0 +0.00397307099774 -0.999991893768 +1.0 -3.32653576152e-06 +0.000747636717279 -0.999999463558 +1.0 0.0 +0.00299150845967 0.999995470047 +1.0 2.34868343796e-06 +1.06849220174e-05 1.0 +1.0 1.31012018301e-06 +0.000367239961633 0.999999880791 +1.0 1.48417684392e-11 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.0885502323508 0.996071338654 +1.0 0.000165037825354 +1.19248761976e-08 -0.999999821186 +1.0 -2.57544485294e-07 +8.83225220605e-05 0.999999821186 +1.0 1.97429372406e-07 +1.0 0.0 +1.0 2.86991394205e-07 +-0.041613869369 0.999133586884 +1.0 6.39233093125e-08 +2.90433472401e-05 0.999999701977 +1.0 1.56322869316e-06 +1.0 8.96575045317e-07 +1.0 1.02078536202e-06 +1.0 9.11719666874e-07 +1.0 2.68098870038e-06 +1.0 5.16670479556e-06 +1.0 5.30867737325e-06 +1.0 6.68238271828e-06 +1.0 5.35878325536e-06 +1.0 6.16815931664e-09 +-1.63034403755e-08 0.999999940395 +1.0 2.33865563359e-07 +1.0 0.0 +9.37382083066e-06 -0.999999880791 +-0.999999761581 -1.98751076823e-05 +-0.999999940395 2.05834408007e-06 +-0.999999940395 2.20855017687e-05 +-0.999999940395 1.84456512216e-05 +-0.999999940395 7.54197117203e-06 +1.0 7.16826434655e-06 +1.0 1.98386260308e-06 +1.0 2.06376271628e-09 +1.0 0.0 +1.0 -2.12009467759e-08 +1.0 -1.08839049062e-06 +0.00532861426473 -0.99998575449 +1.0 -6.85260251321e-11 +0.000871256692335 0.999999463558 +1.0 2.65745597972e-06 +1.0 -8.1855483586e-05 +1.0 1.76776069338e-07 +1.50585151459e-06 0.999999523163 +1.0 3.46535415474e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.106407299638 0.994322359562 +1.0 0.000145427315147 +0.00859913975 -0.999962985516 +-0.999999880791 2.72475233487e-07 +-1.0 1.23051677292e-05 +1.0 9.19731828617e-05 +1.0 0.0 +1.0 9.80207823886e-06 +-0.00163058668841 0.999998450279 +1.0 0.000137271956191 +1.27116763906e-05 0.999999761581 +-1.0 -1.27951568629e-06 +-0.999999880791 1.50995759896e-07 +-1.0 -1.27951568629e-06 +-0.999794602394 -0.0202630851418 +-1.0 7.40607501939e-05 +-0.999999761581 6.58829139866e-06 +-0.999999880791 1.10466987735e-06 +-0.999999940395 5.26030780748e-05 +-0.999999940395 1.50995617787e-07 +-0.999999880791 2.53517987403e-06 +-0.999999940395 1.50995788317e-07 +1.0 1.48576464198e-06 +1.0 0.0 +1.7122425561e-05 -1.0 +1.0 -8.94826314379e-07 +1.0 0.0 +1.0 0.0 +1.0 -3.40324072567e-06 +-1.06213792606e-05 -0.999999940395 +-0.999999880791 2.27435918987e-07 +-0.999999761581 -3.1868635233e-06 +0.999245882034 0.0388244874775 +0.99690759182 -0.0785797685385 +1.0 -1.77939801782e-10 +1.0 0.0 +0.00442461390048 -0.999990165234 +1.0 -9.78989100986e-06 +0.00062854657881 0.999999463558 +1.0 2.88362434731e-06 +1.04911656251e-07 -0.999999940395 +1.0 1.9200224699e-07 +-2.92557285064e-08 0.999999761581 +1.0 2.1312894205e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 8.28013265591e-12 +1.0 3.85561556016e-08 +-0.00280801346526 0.999995589256 +1.0 3.48985777237e-05 +1.0 1.51300537254e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.8571937441e-06 +0.0210904479027 0.999777436256 +1.0 0.000152543361764 +1.04467035271e-05 0.999999821186 +1.0 2.54549121337e-07 +1.0 0.0 +1.0 -4.90362694894e-10 +1.0 4.68250362928e-07 +1.0 4.5074526156e-07 +1.0 5.68340908558e-07 +1.0 6.98636199559e-07 +1.0 5.02372188294e-07 +1.0 7.09367895979e-07 +1.0 6.26082396593e-07 +1.0 7.81297558206e-07 +1.0 5.91343787089e-14 +1.0 0.0 +1.0 -5.70735721794e-07 +1.0 -6.71623740238e-14 +1.0 0.0 +1.0 0.0 +1.0 7.58935243539e-07 +1.0 -4.11668906963e-06 +1.0 1.43723264046e-06 +1.0 4.88132968712e-07 +1.0 4.13523077271e-14 +-0.00445273192599 -0.999989748001 +1.0 -1.75961952209e-06 +1.0 0.0 +1.0 -6.50024958304e-08 +1.0 -1.12185190608e-13 +0.000458131660707 0.999999761581 +1.0 2.98976988233e-06 +1.0 1.0109735058e-06 +0.999991297722 0.00411069020629 +-8.82336479435e-08 0.999999165535 +-0.999999940395 1.60960898938e-05 +0.999997258186 0.00231493380852 +1.0 3.15414126817e-07 +0.999999821186 7.98639030108e-06 +0.999999761581 5.43008754903e-05 +0.999999284744 2.83406934614e-05 +0.99999922514 0.000291676551569 +-1.43052636759e-06 0.999999284744 +1.0 6.13945521764e-05 +-0.000331564689986 0.999999880791 +-0.999992132187 -0.00381024321541 +-0.999996960163 0.00225368025713 +1.0 7.13311646905e-06 +1.0 0.0 +1.0 8.75280420587e-07 +0.0384198203683 0.999261558056 +1.0 8.00646521384e-05 +-0.0015149776591 0.999998569489 +-0.999999761581 -2.78636946405e-07 +-0.999999940395 1.50995788317e-07 +-0.999999940395 3.9013215428e-05 +-0.999999940395 3.8941388425e-07 +-0.999999880791 1.50995759896e-07 +-0.999999821186 1.50995759896e-07 +-0.999999821186 8.97248082765e-06 +-0.999999701977 -1.51793017267e-06 +-0.999999761581 1.50995731474e-07 +-0.999999880791 1.50995774106e-07 +-0.999999880791 1.50995774106e-07 +-1.0 3.89414367419e-07 +-1.0 1.50995802528e-07 +-0.999999940395 1.34308857014e-06 +-0.999999880791 1.34308845645e-06 +-0.999999940395 1.50995745685e-07 +-0.999999880791 6.27832889677e-07 +-0.999999880791 -2.27825989185e-08 +-0.999999403954 -2.2331882974e-06 +-0.999999701977 6.27832662303e-07 +-0.999999940395 6.2783277599e-07 +1.0 1.39664496146e-06 +-0.000703249126673 -0.999999582767 +1.0 -2.11661426874e-06 +1.0 1.65816745721e-05 +1.0 2.40517377065e-15 +1.0 0.0 +1.0 7.73411201749e-08 +1.0 3.2786609121e-14 +1.0 2.4133977039e-09 +0.000130420696223 0.999999523163 +-0.999999403954 -0.000684101949446 +-0.999999523163 -5.57104704058e-06 +-0.999999940395 -2.23318988901e-06 +-0.999999701977 -5.64255401514e-07 +-0.999999403954 -1.99476517082e-06 +-0.999999701977 -1.99477040042e-06 +-0.999998986721 -1.04109597032e-06 +-0.999998211861 1.34308493216e-06 +-0.999999165535 0.000374034250854 +1.0 6.9651818194e-05 +7.54978799478e-08 0.999999880791 +1.0 6.94988148098e-06 +1.0 4.87028228235e-06 +1.0 2.85724872581e-12 +1.0 0.0 +1.0 3.1769681641e-07 +0.00232977606356 0.999997079372 +1.0 7.06400487616e-06 +0.149134323001 0.988816201687 +1.0 4.79807056308e-07 +1.0 3.39244053293e-07 +1.0 2.31283252106e-07 +1.0 3.20013157307e-07 +1.0 -3.46474394064e-07 +4.6767960157e-05 -0.999999761581 +1.0 2.72291259762e-07 +1.0 7.76090359977e-07 +1.0 6.29169733202e-07 +-0.00910655036569 0.999958097935 +1.0 3.61373110991e-07 +0.000837337749545 -0.999999523163 +1.0 3.07361574414e-07 +1.0 3.15307715937e-07 +1.0 2.96010938428e-07 +1.0 3.21788490965e-07 +1.0 2.21252139454e-06 +1.0 4.70387603855e-05 +1.0 8.09186758488e-07 +1.0 3.10951492111e-07 +0.000185501543456 -0.999999821186 +1.0 -3.67679895135e-05 +-0.0762801840901 -0.997086405754 +1.0 -1.88543447166e-06 +1.0 5.05260935313e-08 +1.0 8.34743028585e-16 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.000129536740133 0.999999821186 +1.0 1.22394940263e-05 +1.0 2.102734652e-05 +1.0 1.65521068993e-05 +1.0 1.6784248146e-05 +1.0 1.65505789482e-05 +1.0 1.78887839866e-05 +1.0 1.97057506739e-05 +1.0 1.77090932993e-05 +1.0 8.63758396008e-06 +1.0 1.46619640873e-05 +7.54978302098e-08 0.999999642372 +1.0 0.0 +0.00524275330827 0.999985873699 +1.0 8.60670894554e-08 +1.0 0.0 +1.0 3.60116018783e-07 +0.000233964092331 0.999999940395 +1.0 1.78999228634e-11 +0.152960091829 0.988232135773 +1.0 1.32342474899e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -7.31238344542e-07 +1.70032126334e-05 -0.999999940395 +1.0 0.0 +1.0 -1.67335874721e-05 +1.0 1.03780905647e-06 +4.12861299992e-06 0.999999880791 +-0.00163762061857 0.999998450279 +0.000965312879998 -0.999999463558 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +8.14082046219e-09 0.999999940395 +-0.999998092651 0.00188094493933 +1.0 0.00021767927683 +1.0 0.0 +0.00364048057236 -0.999993383884 +-2.07026914723e-06 -0.999999940395 +-1.17262179629e-05 -0.999999821186 +-0.999999463558 5.12100132255e-06 +-0.999999940395 -3.18686375067e-06 +-0.999999880791 -1.04109687982e-06 +-0.999999880791 1.50995774106e-07 +-0.999999880791 -3.25444688087e-07 +-0.999999821186 -8.0266340774e-07 +1.0 4.26447513746e-07 +0.000642732484266 0.999999582767 +1.0 8.70289852628e-07 +0.999999523163 0.000338714191457 +1.0 -2.16263920834e-12 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.03024023399e-06 +1.66455738508e-05 0.999999284744 +1.0 3.44320362153e-12 +-4.41043266619e-06 0.999999940395 +1.0 2.1058825439e-07 +1.0 3.02585876209e-15 +1.0 8.46227578677e-07 +7.10931900016e-08 0.999999940395 +1.0 2.15893532977e-13 +0.0968907177448 0.995294749737 +1.0 6.43937528366e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -1.42701196637e-07 +-0.00194768363144 -0.999998033047 +1.0 0.0 +0.000301134801703 -0.999999880791 +1.0 -2.80185377051e-05 +6.03596072324e-06 0.999999761581 +7.54978515261e-08 0.999999761581 +0.000943855207879 -0.999999463558 +1.0 7.02023100985e-07 +1.0 5.58786098281e-07 +1.0 4.90304046252e-07 +1.0 3.84411890764e-07 +1.55645648192e-05 0.999999821186 +1.0 4.27211898568e-06 +1.0 0.0 +1.0 0.0 +1.0 -4.29745981023e-08 +1.0 3.16611306062e-08 +1.0 2.14746975757e-07 +1.0 1.22013432247e-06 +1.0 1.03349952951e-06 +1.0 6.56951101519e-07 +1.0 6.86721762122e-07 +1.0 9.2854503464e-07 +0.000292312644888 -0.999998390675 +1.0 -2.16491321398e-12 +0.0186612047255 0.999825775623 +1.0 2.38256325247e-06 +7.12434339221e-05 -0.999999880791 +1.0 -2.24848622565e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.81697518037e-08 +1.0 2.57577789853e-06 +6.31371876807e-05 0.999999701977 +1.0 4.89383126023e-07 +-0.0888835191727 0.996041893959 +1.0 2.45339819571e-08 +1.0 6.69288738209e-07 +5.31235236849e-05 1.0 +-0.999999880791 -2.79140380144e-07 +1.0 1.10347309601e-05 +0.0100127691403 0.99994969368 +1.0 0.000117076378956 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -1.26695880454e-07 +0.000805149262305 -0.999999523163 +1.0 5.95324969876e-11 +0.000651672889944 -0.999998927116 +1.0 -2.6799587431e-05 +4.9255831982e-06 0.999999761581 +9.01618022908e-06 0.999999880791 +-0.00294015463442 -0.999993264675 +-0.999999821186 2.05810874832e-06 +-0.999999940395 3.72727390641e-06 +-0.999999940395 7.54196980779e-06 +-0.999999880791 0.000160129799042 +-1.0 2.0416573534e-05 +1.0 4.08708729083e-06 +1.0 -2.37563622107e-08 +0.999872505665 -0.0159645434469 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +7.84628326755e-08 -0.999999880791 +1.0 -1.19845287827e-06 +0.00373310502619 0.999992847443 +1.0 3.09264783027e-06 +0.000154332286911 -0.999999940395 +1.0 -1.9668304958e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.000216436339542 0.999999701977 +1.0 3.48621483681e-06 +-7.10799108461e-09 0.999999821186 +1.0 1.51968220052e-06 +4.00940280088e-06 0.999999880791 +1.0 2.31598051309e-16 +1.0 5.37784387689e-07 +0.000570253236219 0.999999463558 +1.0 1.51782761164e-13 +1.0 1.04922048649e-06 +0.11379430443 0.993504226208 +1.0 6.21594663244e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.82281476697e-13 +1.98166773657e-07 0.999999940395 +1.0 1.43120487905e-07 +0.0242903865874 -0.99970471859 +1.0 -1.46969632624e-05 +0.99687743187 0.0789645984769 +0.00638336362317 0.999979197979 +1.0 9.79502715381e-07 +1.0 1.7642412331e-06 +1.0 1.77502022325e-06 +1.0 3.99132800649e-14 +1.0 -8.90998364866e-07 +1.0 -1.19902663644e-13 +1.0 5.35189940365e-07 +1.0 -2.44036655204e-05 +7.04487274561e-06 -0.999999642372 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -5.56478198632e-07 +1.0 1.11041276796e-06 +0.00014504500723 1.0 +1.0 1.96965958355e-14 +0.00031657438376 -0.999999821186 +1.0 -1.95570419237e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-2.06344719089e-08 0.999999761581 +1.0 1.05671620076e-06 +3.51230082742e-05 0.999999880791 +1.0 1.07900029889e-06 +0.0386057905853 0.999254286289 +1.0 0.0 +1.0 5.28996793037e-07 +0.00110252236482 0.999999344349 +1.0 4.23438405051e-06 +-1.78577963084e-07 0.999999344349 +-0.999999821186 2.05834135159e-06 +1.0 5.81203785259e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.79580723625e-07 +1.17579975267e-05 0.999999940395 +1.0 3.97470989769e-14 +0.0012433459051 -0.999999165535 +1.0 -5.46085175301e-06 +1.0 0.0 +1.0 0.0 +6.3318067987e-05 1.0 +-0.999999880791 -1.54911834471e-08 +-0.999999821186 -3.18686375067e-06 +1.0 -2.78700304079e-06 +0.99890422821 -0.0467986501753 +1.0 -5.0371911503e-11 +0.00517218466848 0.999986469746 +1.0 9.73611622612e-06 +6.71544228226e-07 -0.999999880791 +1.0 3.67285167613e-07 +-0.00684903515503 0.999976038933 +-0.999999701977 -0.000387994252378 +-0.999999642372 -2.15450872929e-05 +-0.999999880791 6.58829549138e-06 +-0.999998986721 0.00139251491055 +1.0 0.00016382324975 +1.0 0.0 +1.0 0.0 +1.0 3.73787779158e-14 +1.0 1.90527600807e-07 +1.0 0.0 +0.00143976532854 -0.999998867512 +-0.999956309795 -0.00934253167361 +-0.999999880791 0.000232132108067 +-0.999999880791 6.19013735559e-05 +-0.999999761581 5.87303975408e-06 +-0.999999940395 5.59409381822e-05 +-0.999999821186 2.77359936263e-06 +-1.0 6.2783294652e-07 +1.0 3.87814043279e-06 +0.00305731128901 0.999995112419 +1.0 7.00376915574e-07 +0.00266416044906 0.999996125698 +1.0 0.0 +1.0 6.57792725178e-07 +-0.0105380639434 0.999944031239 +1.0 7.68302652432e-06 +-0.050080832094 0.9987449646 +1.0 4.18247282141e-06 +1.0 7.66231522675e-12 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 2.23433843871e-07 +1.14837939691e-06 1.0 +1.0 0.0 +1.0 -2.74769611508e-08 +1.0 -2.24232626553e-14 +1.0 0.0 +1.0 0.0 +0.00013513956219 0.999999821186 +1.0 1.20198887998e-06 +1.68840015249e-05 -0.999999642372 +1.0 -2.40866188506e-06 +7.54978728423e-08 -0.999999701977 +1.0 -1.98856628231e-06 +-0.00385096971877 0.999992251396 +1.0 2.75662641798e-05 +-0.00127367477398 -0.999998688698 +1.0 7.69933649281e-07 +1.98284578801e-06 0.999999701977 +1.0 -2.20934043682e-06 +-5.76853526582e-05 -0.999999701977 +1.0 5.54078724235e-06 +1.0 3.27205293615e-06 +1.0 8.53781045862e-07 +1.0 1.20652748592e-06 +1.0 8.93878564057e-07 +1.0 1.74845212086e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 7.41254211789e-07 +1.0 9.91776460069e-07 +1.0 1.05721312593e-06 +1.0 1.29415820993e-06 +1.0 1.09503787371e-06 +1.0 1.24304335714e-06 +1.0 1.48232049924e-06 +1.0 2.83229602965e-13 +0.0670382231474 0.997750163078 +1.0 1.85608814718e-06 +0.0264439210296 0.999650061131 +1.0 2.32148544832e-09 +1.0 9.53628023126e-06 +-0.000682754733134 0.999999523163 +1.0 6.28406780834e-07 +0.00146265362855 0.999998867512 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.75403954472e-07 +2.86857175524e-05 0.999999880791 +1.0 0.0 +1.0 -2.49049644481e-05 +1.0 -2.63897627709e-12 +1.0 0.0 +1.0 0.0 +4.72465899293e-06 0.999999821186 +1.0 1.72742500126e-06 +9.58005257417e-05 -0.999999880791 +1.0 -1.74428396349e-06 +-0.154328852892 -0.988019406796 +1.0 -2.98095874314e-05 +1.34269366754e-05 0.999999880791 +1.0 1.99889063879e-06 +-0.0231704562902 -0.999731302261 +1.0 -1.31858740815e-07 +1.98284578801e-06 0.999999940395 +1.0 -5.72923738673e-07 +-0.00418630242348 -0.999990880489 +-0.999999880791 -5.3688013395e-06 +-0.999999880791 -1.03553861663e-06 +-0.999999880791 -1.27951545892e-06 +-0.999999821186 -2.23318943426e-06 +-0.999999821186 -1.75635238975e-06 +-0.999998927116 -2.23318716053e-06 +1.0 -6.62606953483e-06 +1.0 -3.98709344154e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +2.45968340096e-06 0.999999880791 +1.0 2.8513570669e-06 +0.00124724255875 0.999999165535 +1.0 7.23421578641e-07 +1.0 0.000129546489916 +0.000461057235952 0.999999761581 +1.0 7.07144522494e-07 +0.000423029327067 0.999999403954 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.69072606582e-07 +0.000152782507939 0.999999940395 +1.0 0.0 +3.49489397422e-08 -0.999999821186 +1.0 -1.36781000037e-06 +1.0 0.0 +1.0 0.0 +0.00209934916347 0.999997675419 +1.0 2.67654741037e-06 +1.0 -1.87363951909e-07 +1.0 -4.67567269082e-14 +1.0 -3.560967059e-07 +1.0 -2.6733500396e-12 +2.2807678306e-06 0.999999940395 +1.0 2.02346473088e-06 +0.0472494922578 -0.998883008957 +1.0 3.49611077866e-08 +0.000291422824375 0.999999403954 +1.0 -5.25160260167e-07 +3.47985733242e-05 -1.0 +0.999601960182 0.0282053183764 +0.999999165535 0.000731965410523 +0.999611914158 0.0278535857797 +0.999984800816 0.00543697690591 +0.999999761581 7.28964960217e-06 +1.19248610986e-08 -0.999998867512 +1.0 -1.84218042705e-05 +1.54373374244e-05 -0.999999880791 +1.0 1.64027580581e-12 +1.0 6.20407263341e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.627509381e-14 +1.0 1.71539866756e-07 +1.94707169499e-07 0.999999940395 +1.0 3.51196672455e-06 +0.000335410994012 0.999999940395 +1.0 8.41477742597e-07 +1.0 0.000126971339341 +0.00161524082068 0.99999833107 +1.0 1.01432340216e-06 +3.54806397809e-05 0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 2.22493369506e-07 +2.10205485018e-06 0.999999761581 +1.0 0.0 +7.54978941586e-08 -0.999999940395 +1.0 -1.37659196753e-06 +1.0 0.0 +1.0 0.0 +0.000166815676494 0.999999761581 +-0.999999880791 0.000231588812312 +-0.999999821186 8.16901228973e-05 +-0.999999880791 8.21669673314e-05 +-0.999999463558 0.000297697202768 +-0.999999701977 0.000118168121844 +-0.999998688698 0.00155255687423 +1.0 7.33908109396e-07 +-2.35275419982e-05 -0.999999701977 +-0.99999576807 0.00236018747091 +-0.999996602535 0.00257077696733 +1.0 -5.25695440956e-07 +4.35050606029e-05 -0.999999940395 +0.999999880791 3.6242108763e-06 +1.02917204003e-06 0.999999940395 +1.0 2.28442013395e-06 +1.0 3.20193271364e-06 +1.0 2.06635218092e-06 +-4.37113740759e-08 -0.999999642372 +1.0 -5.21507427038e-05 +-0.0317018888891 -0.999497115612 +1.0 2.0656000288e-06 +-2.27162017836e-05 0.999999761581 +-0.999999046326 0.000562817847822 +-0.999999523163 0.000971468049102 +-0.999999582767 0.000798376160674 +-0.999996900558 0.00241127517074 +-0.999983429909 0.00574501696974 +-0.999999701977 0.000293405697448 +-0.998585879803 0.0531608201563 +-0.999890625477 0.0147787099704 +1.0 3.73650141228e-06 +0.00140984356403 0.999998688698 +1.0 6.71672864883e-07 +1.0 5.32484664291e-05 +0.0216625649482 0.9997651577 +-0.999997973442 0.0019544030074 +-0.999999582767 0.000480266811792 +1.0 2.13348744182e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 2.56348243965e-07 +9.66020294868e-08 1.0 +1.0 0.0 +-4.37113776286e-08 -0.999999761581 +1.0 -1.85023577615e-06 +1.0 0.0 +1.0 0.0 +-0.0143553270027 0.999896764755 +1.0 4.276355412e-06 +1.0 2.31872400036e-06 +1.0 2.47096545536e-06 +1.0 2.15665386349e-06 +1.0 2.44986904363e-06 +1.0 1.53312964812e-06 +1.0 1.09506147368e-13 +1.0 4.13307907365e-06 +1.0 2.85590090243e-06 +1.0 2.46925537795e-06 +1.0 -5.4812670669e-07 +2.68975818472e-05 -0.999999761581 +0.999998986721 0.000359894009307 +1.94707155288e-07 0.999999761581 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-4.37113669705e-08 -0.999999582767 +1.0 -0.000122787430882 +6.65903644403e-05 -0.999999940395 +1.0 1.211586914e-05 +-6.39757729459e-07 0.999999940395 +1.0 1.64588709595e-06 +1.0 -7.78828791681e-07 +1.0 1.45178137245e-06 +1.0 1.21893310734e-06 +1.0 1.16134879136e-06 +1.0 1.59960063684e-06 +1.0 3.5468601709e-05 +1.0 1.31716087708e-05 +1.0 4.2146564283e-07 +2.85657115455e-05 0.999999880791 +1.0 1.00123088487e-06 +0.999999821186 0.000351556373062 +0.0249155666679 0.999689221382 +1.0 1.90485206986e-05 +3.57940149742e-10 -0.999999880791 +1.0 2.886467107e-12 +0.0129777966067 0.999915599823 +-0.999999821186 1.19423964406e-06 +-0.999999940395 3.89414338997e-07 +-0.999999880791 9.64720893535e-05 +-0.999999821186 6.11145924267e-06 +-0.999999940395 0.000350647023879 +1.0 0.0 +-4.37113776286e-08 -0.999999701977 +1.0 -1.93492655853e-06 +1.0 0.0 +1.0 0.0 +1.0 5.65224618185e-05 +1.0 3.51501748715e-12 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -9.44132683145e-09 +0.999999880791 -2.92277832159e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -4.3547655082e-07 +4.99049783684e-05 -0.999999940395 +0.999991714954 0.00402316637337 +0.999998927116 -4.60443989141e-05 +1.0 -6.07590866508e-10 +1.0 0.0 +1.0 0.0 +7.54978941586e-08 -0.999999940395 +1.0 -8.32646037452e-06 +2.78512507066e-05 -0.999999761581 +1.0 3.42544376508e-06 +-0.000170870378497 0.999999403954 +1.0 -5.06280400714e-07 +0.000880865612999 -0.999999403954 +0.999825954437 -0.0186575036496 +1.0 -1.66375659916e-08 +1.0 0.0 +1.0 0.0 +2.73999152256e-08 1.0 +-0.999999940395 1.93033565665e-06 +-0.999999940395 3.48885555468e-06 +-1.0 2.94101778309e-06 +1.0 3.21212183962e-07 +1.0 5.85454981774e-05 +0.00247449940071 0.99999666214 +1.0 -8.37358982153e-08 +7.54978870532e-08 -0.999999940395 +1.0 0.0 +7.54978870532e-08 0.999999880791 +1.0 1.06575805603e-06 +1.0 5.16514091942e-07 +1.0 3.27617215135e-07 +1.0 4.2954059154e-07 +1.0 2.87435113933e-07 +1.0 0.0 +7.54978728423e-08 -0.999999701977 +1.0 -1.53155656335e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -1.61772356932e-06 +7.83538780524e-07 -0.999999880791 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -8.03587543187e-14 +1.0 -1.10653866159e-06 +1.0 2.27191918611e-08 +1.0 -7.71430297419e-09 +1.0 5.63415085253e-07 +1.0 2.41135012402e-07 +1.0 2.10257070421e-07 +1.0 1.51193930265e-07 +1.0 -7.78833793902e-07 +0.012081339024 -0.999926865101 +1.0 2.7897306154e-06 +7.54977378392e-08 0.999999821186 +1.0 -2.48824647997e-07 +1.86721463251e-05 -1.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-9.63642160059e-05 0.999999880791 +1.0 1.30167691168e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 5.30427823833e-05 +0.023577593267 0.9997215271 +1.0 -1.05575871601e-07 +7.54976454687e-08 -1.0 +1.0 0.0 +5.79753532293e-06 0.999999821186 +1.0 4.51857061989e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-5.17805347044e-05 -0.999999880791 +1.0 -1.2142807293e-07 +1.0 0.0 +1.0 0.0 +-0.00249199103564 0.999996483326 +-0.999999880791 -3.66370090887e-06 +-0.999999701977 -1.99477062779e-06 +-0.999999821186 -1.99477108254e-06 +-0.999999821186 -1.99477108254e-06 +-0.999933540821 -0.0115097248927 +1.0 9.76517003437e-06 +0.00194056180771 -0.999997675419 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.25775818055e-06 +0.0619396679103 0.998079478741 +-0.999999940395 -4.2682675172e-08 +-0.999999940395 2.29676288654e-06 +-0.999999940395 0.000183971700608 +-0.999998927116 0.00141492602415 +-1.0 3.89387594169e-07 +1.0 2.15427292005e-07 +1.0 2.24691416406e-06 +1.94707155288e-07 0.999999821186 +1.0 -3.92312927033e-07 +5.5233368812e-07 -0.999999701977 +1.0 0.0 +1.0 -3.88800581277e-05 +1.0 -1.9995886457e-12 +1.0 0.0 +1.0 4.72744829949e-07 +1.0 3.13715714647e-13 +1.0 6.74395594924e-10 +0.000964796403423 0.999999463558 +1.0 1.0427300623e-07 +1.0 6.40849102638e-05 +0.00982645526528 0.999951422215 +1.0 -8.39638687467e-08 +5.32070635018e-06 -1.0 +1.0 0.0 +7.22805452824e-06 0.999999940395 +1.0 4.34985480524e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +5.99185441388e-05 0.999999761581 +1.0 4.42960708824e-06 +1.0 7.03685088865e-07 +1.0 2.62087610281e-07 +1.0 4.41876267132e-07 +1.0 2.91120016982e-07 +1.0 -1.14914018923e-06 +1.09235352284e-05 -0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 2.10217808672e-06 +0.000103549136838 0.999999761581 +-0.155597805977 0.987820327282 +1.0 4.11229530073e-06 +1.0 0.0 +1.0 0.0 +1.0 4.38234292233e-06 +0.00154109310824 0.999998629093 +1.0 2.12426334656e-06 +7.53581304025e-08 0.999999821186 +1.0 -2.35366837842e-06 +0.00274105067365 -0.999996125698 +1.0 -4.39857941465e-15 +-4.3711384734e-08 -0.999999880791 +1.0 -7.27025451397e-07 +1.0 -7.12746768272e-08 +1.0 -1.25857183291e-13 +1.0 3.42476681681e-07 +1.0 3.03231217913e-06 +-0.00100986461621 0.999998807907 +1.0 6.85171308579e-10 +1.0 5.32698650204e-05 +0.0224436242133 0.999747931957 +1.0 -6.97539306316e-08 +6.71541215524e-07 -1.0 +1.0 0.0 +-7.47970130277e-09 0.999999821186 +1.0 6.66597316012e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 5.01665317643e-06 +1.0 2.10904725758e-13 +0.0212736278772 0.999773383141 +1.0 4.43102635472e-06 +0.00231098430231 0.999997317791 +1.0 1.20513300317e-06 +2.64989830612e-06 1.0 +1.0 1.11921309554e-07 +2.57889291788e-06 0.999999940395 +2.27252603509e-05 -1.0 +-0.999999880791 1.04658582245e-07 +-0.999999761581 7.90675258031e-05 +-0.999999821186 6.85770646669e-05 +-0.999999880791 5.15778492627e-06 +-0.998633146286 -0.0522600114346 +1.0 1.85555200005e-06 +0.000277236453258 0.999997615814 +0.0442332178354 0.999020040035 +-0.0666278377175 0.99777752161 +-0.999999821186 1.75555451278e-05 +-0.999999582767 0.000545652525034 +-0.999999880791 0.000144871039083 +-0.978288888931 0.207244515419 +1.0 2.34286244449e-06 +0.166906073689 0.98597240448 +1.0 -1.09946267912e-05 +1.84644246559e-08 -0.999999701977 +1.0 -4.52312747257e-07 +-1.39803535415e-09 -0.999999940395 +1.0 -4.08623861858e-07 +0.999884963036 -0.0151570979506 +1.0 -1.63723871083e-05 +0.0112522393465 0.999936640263 +1.0 5.0819057833e-06 +4.22755801992e-05 0.999999940395 +1.0 0.0 +1.0 1.52806660481e-05 +0.106603123248 0.994301319122 +1.0 -8.08359530424e-08 +7.54935811642e-08 -0.999999940395 +1.0 0.0 +1.0 4.33954664913e-06 +1.0 2.37945839247e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +6.98963640389e-06 1.0 +1.0 2.93317924616e-07 +0.998458862305 0.0554929338396 +0.999931812286 0.0116494735703 +0.999999821186 2.49407818842e-08 +-0.996289253235 0.0860649868846 +-1.0 8.78104231106e-07 +-0.999999821186 1.58150703555e-06 +-0.99999833107 0.00126966496464 +1.0 -4.74470255085e-07 +1.0 1.98097905013e-06 +1.0 1.18982404729e-06 +1.0 1.09903282919e-06 +1.0 -3.01991605056e-07 +1.19248735331e-08 -0.999999940395 +1.0 4.05907712775e-07 +0.105570629239 0.994409918785 +0.124582149088 0.992209196091 +0.0392944477499 0.999227583408 +1.0 6.52148719382e-06 +1.0 5.15856709171e-06 +1.0 6.20491982772e-06 +1.0 5.76321838253e-07 +1.0 3.76187585971e-07 +-2.73867417633e-09 0.999999940395 +1.0 -9.00487611943e-06 +-8.50398646435e-05 -0.99999922514 +1.0 -6.19823481429e-07 +1.14838098852e-06 -0.999999582767 +1.0 -7.47543538182e-08 +0.00282843085006 -0.999995827675 +1.0 -1.17210402095e-05 +3.29414706357e-06 0.999999940395 +1.0 6.6510083343e-06 +2.08179098991e-05 0.999999880791 +1.0 0.0 +1.0 5.80238463499e-07 +3.45263360941e-05 0.999999940395 +1.0 -7.55976534848e-16 +1.0 -4.43692336205e-08 +1.0 0.0 +1.0 0.0 +1.0 1.3262608107e-14 +1.0 2.26354245569e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-5.15137621449e-09 0.999999880791 +1.0 5.23672042618e-07 +1.0 3.59747301393e-11 +1.0 1.41721375257e-06 +1.0 -2.97278290873e-07 +9.15133398394e-07 -0.999999821186 +1.0 -4.11668906963e-06 +1.0 4.59830198452e-06 +0.000561669934541 0.999998927116 +-0.999999880791 -1.22263837943e-10 +-0.999999880791 1.50995774106e-07 +-0.999999940395 -1.99477130991e-06 +-0.999999582767 -0.000259963562712 +1.0 -1.75110898226e-07 +7.54978870532e-08 -0.999999880791 +1.0 3.36896987087e-14 +5.55912492928e-06 0.999999940395 +0.000311441282975 0.999999582767 +0.10816642642 0.994132637978 +1.0 7.77956472575e-07 +-0.0509979277849 0.998698115349 +-0.999999821186 -5.90139981327e-09 +-0.999999940395 1.50995788317e-07 +-0.999999821186 1.50995759896e-07 +-1.0 0.000158581489814 +1.0 -7.0356395554e-06 +-4.45445448349e-06 -0.999999880791 +1.0 -8.65283027451e-07 +-2.90473326459e-06 -0.999999642372 +1.0 -1.91186629195e-07 +0.0549639575183 -0.998488247395 +1.0 -5.67830147702e-06 +0.000382141122827 0.999999642372 +1.0 5.10751351612e-06 +0.000144795529195 0.999999821186 +1.0 0.0 +1.0 1.37289134727e-07 +0.99399882555 0.109387613833 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 3.41032404094e-07 +6.27437975709e-06 0.999999821186 +-0.999999880791 6.92038156558e-06 +-0.999999880791 -1.99477108254e-06 +-1.0 -1.2795147768e-06 +-0.999999880791 -0.0001059452552 +-0.999999344349 -0.000913248164579 +-0.999999940395 1.81992538728e-06 +-1.0 8.01290582331e-07 +-0.999999940395 -2.47160846811e-06 +-0.999999940395 -1.51793392433e-06 +-1.0 -4.79317577629e-06 +0.999999821186 1.55711477419e-05 +0.130238711834 -0.99148195982 +-0.999999940395 -5.39624625162e-06 +-0.999999880791 -1.99477108254e-06 +-0.999999880791 2.05834408007e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-1.29594104337e-08 -0.999999940395 +1.0 -5.05827301822e-07 +-4.3711384734e-08 -0.999999880791 +1.0 0.0 +1.35461459649e-05 0.999999940395 +0.000143683995702 0.999999880791 +0.0362447202206 0.999341964722 +1.0 2.51488540925e-06 +0.00926750712097 0.999956727028 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -3.09133708215e-12 +1.0 -2.54416522694e-06 +1.0 -2.5237378054e-07 +-2.82127700757e-07 -1.0 +1.0 -1.04604239937e-07 +1.0 0.0 +1.0 0.0 +2.84269699478e-05 0.999999761581 +1.0 5.58843612453e-06 +0.000124291560496 1.0 +1.0 0.0 +1.0 0.0 +1.0 -4.01901800728e-08 +1.0 -7.5782165848e-15 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.86203873606e-07 +-1.93921834146e-09 0.999999642372 +1.0 4.15000795329e-05 +1.0 2.11587718013e-07 +1.0 1.87806918461e-07 +1.0 1.09988896213e-07 +1.0 2.00670478989e-06 +1.0 2.28196768148e-06 +1.0 2.70941109193e-06 +1.0 1.98200538648e-07 +1.0 2.50657336665e-07 +1.0 2.50038539207e-07 +1.0 1.94589466068e-11 +1.0 -3.20721574099e-06 +1.0 2.30418478964e-07 +1.0 3.38415361512e-07 +1.0 2.08477061392e-07 +1.0 0.0 +1.0 0.0 +1.0 -8.37440446849e-12 +-4.36917986235e-08 -0.999999880791 +1.0 -4.54283906492e-07 +-4.37113811813e-08 -0.999999821186 +1.0 0.0 +5.20149569638e-06 1.0 +0.0670653432608 0.997748315334 +0.000369385845261 0.999999880791 +1.0 5.5074553984e-07 +1.94707155288e-07 0.999999880791 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.998230397701 -0.0594648383558 +1.0 -8.20787818157e-07 +-0.000250550248893 -0.999999582767 +-1.0 1.00515444501e-06 +-0.999999761581 -1.29620220832e-05 +-0.999620437622 -0.0275325048715 +-0.996206879616 0.0870099961758 +1.0 5.08809853272e-06 +7.77999448474e-05 0.999999880791 +1.0 0.0 +1.0 0.0 +0.999999940395 -5.74301793677e-07 +1.0 -1.77602214535e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 7.71539882221e-14 +1.0 1.36403855322e-07 +1.0 5.61383421882e-06 +1.0 0.0 +1.0 0.0 +0.000808075710665 0.999999403954 +1.0 1.13718067496e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -5.00830221739e-09 +0.999999761581 -2.19730372919e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -1.14583521338e-07 +2.70626278507e-05 -0.999999940395 +1.0 -3.16047021443e-06 +7.54978870532e-08 -0.999999821186 +1.0 0.0 +5.25275827385e-05 1.0 +0.0642600730062 0.997933149338 +0.00191648257896 0.999997973442 +1.0 8.05907461654e-07 +-8.39526492769e-09 0.999999880791 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -8.40342639918e-09 +1.0 -4.13127729726e-13 +1.0 4.27977010986e-06 +1.0 1.1306820852e-05 +1.0 9.56165240495e-06 +1.0 8.90419778443e-06 +1.0 3.59505133929e-06 +1.0 3.71904934582e-06 +3.69813655254e-08 0.999999821186 +1.0 0.0 +1.0 0.0 +7.54978586315e-08 -0.999999880791 +1.0 -1.75847139872e-06 +0.999999582767 0.000437666894868 +1.0 3.32417871007e-10 +1.0 3.11409650067e-07 +1.0 2.47519835739e-07 +1.0 3.82567890256e-07 +1.0 3.0103265658e-07 +1.0 1.54717895384e-07 +1.0 0.0 +4.12859526477e-06 0.999999821186 +1.0 1.82358178336e-06 +1.0 0.0 +1.0 0.0 +1.0 4.2628202209e-05 +1.0 2.17563055245e-12 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -2.5150836791e-07 +1.14263787054e-06 -0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -6.08107825428e-07 +1.0 -1.55576174166e-07 +3.13916416417e-07 -0.999999821186 +1.0 0.0 +5.52334995518e-07 0.999999880791 +0.00837216060609 0.999964773655 +2.59439129877e-05 0.999999940395 +1.0 1.36846819141e-13 +1.0 2.56428279499e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 4.73909931316e-05 +0.0401025004685 0.999195456505 +-0.999999701977 -1.75634750121e-06 +-0.999999940395 5.45782713743e-05 +1.0 0.0 +1.0 0.0 +1.06851202872e-05 -0.999999642372 +1.0 -2.8525153084e-06 +8.03031252872e-06 0.999999761581 +1.0 8.12598500488e-06 +9.27424803621e-09 1.0 +-0.999999523163 0.000842740118969 +-0.999999880791 -2.94844244308e-06 +-0.999999940395 1.50995759896e-07 +-0.999999582767 0.000835719751194 +1.0 -3.93108440807e-16 +0.999999403954 0.000489381956868 +1.0 4.55303052149e-07 +1.0 0.0 +1.0 1.00090680633e-07 +-2.1894782094e-06 0.999999880791 +-0.999999940395 0.000163229298778 +-0.999999761581 8.55048128869e-05 +-0.999999642372 0.000264795409748 +-0.999999940395 1.20719178085e-05 +1.0 1.74337674252e-05 +0.0410331264138 -0.999157428741 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -2.71493121318e-07 +0.0544721111655 -0.998515129089 +1.0 0.0 +5.08228640683e-06 0.999999701977 +-0.157432630658 0.987529158592 +0.000348047411535 0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.5450794308e-05 +1.0 1.80923036969e-11 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 8.27994917074e-09 +-4.36987086516e-08 0.999999940395 +1.0 9.71386953097e-07 +1.0 8.80627851529e-07 +1.0 3.10150464881e-14 +1.0 0.0 +-0.00243636826053 -0.999996840954 +-0.999999821186 -3.18385384723e-09 +-1.0 8.76582180354e-06 +-0.999999880791 9.38574612519e-06 +-0.999999284744 0.000292113167234 +1.0 2.24244540732e-05 +1.0 0.0 +1.0 -1.62593778441e-08 +-4.36216609501e-08 -0.999999523163 +1.0 -1.92361525819e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 6.60648083795e-07 +-4.37113776286e-08 0.999999940395 +1.0 1.7354764168e-06 +1.0 4.00979552069e-05 +1.0 5.88664261159e-06 +1.0 5.69640405956e-06 +1.0 -4.05478704124e-06 +0.0119238151237 -0.999928474426 +1.0 0.0 +0.0363284051418 -0.99933975935 +1.0 -2.69812085207e-06 +1.0 3.05274011225e-06 +1.0 0.0 +1.0 -1.02553294361e-14 +1.0 -1.84089273603e-07 +1.0 0.0 +-3.65082253317e-09 0.999999701977 +0.0167820695788 0.99985897541 +9.09962864171e-07 0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +2.32373622566e-05 0.999999940395 +1.0 1.14976664918e-05 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 8.51409640745e-06 +1.0 5.37703616441e-13 +0.000222591406782 1.0 +1.0 2.49187877444e-07 +1.0 7.54941508613e-12 +1.0 -2.12182167161e-05 +1.0 1.0063749869e-06 +-9.04936292567e-10 -1.0 +1.0 2.18025135723e-07 +1.0 4.5445611363e-07 +1.0 -1.13777761626e-13 +1.0 -1.73988191818e-05 +1.0 -3.55912241901e-08 +-2.20248894038e-05 -0.999999582767 +-0.999999821186 -1.25222541669e-07 +-0.999999761581 1.50995759896e-07 +-0.999999880791 -2.94844517157e-06 +-1.0 -4.41526225359e-07 +1.0 1.03333456991e-06 +-4.11480840512e-08 0.999999940395 +1.0 3.39477253419e-07 +1.62521644143e-06 0.999999821186 +-0.999999821186 8.24053931865e-05 +-0.999999940395 7.81138660386e-05 +1.0 1.05977242129e-05 +0.00025148774148 -0.999999463558 +1.0 0.0 +0.000554278376512 -0.99999922514 +1.0 -3.97627854909e-06 +4.94281375722e-05 0.999999880791 +1.0 0.0 +-0.00029890119913 0.999999344349 +-0.999998390675 0.000279815547401 +-1.0 1.81992527359e-06 +-0.999999701977 2.6533602977e-06 +-0.99999910593 0.000292690354399 +-0.999999701977 7.78038429416e-06 +1.0 3.25458813677e-07 +1.0 0.0 +1.0 0.0 +1.0 2.8524121376e-07 +1.0 3.34005772259e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.50601169935e-06 1.0 +1.0 2.69460116442e-07 +1.0 2.36333016801e-05 +0.00473576504737 0.999988734722 +1.0 0.0 +-4.01339150358e-07 -0.999999761581 +-0.999999940395 1.32004433908e-05 +-0.999999880791 -0.000338641752023 +1.0 -9.04914941202e-06 +-1.64590101548e-08 -1.0 +1.0 0.0 +1.0 -5.07036429553e-06 +1.0 1.25208339341e-06 +1.0 1.38471136779e-06 +1.0 1.40957433814e-06 +-4.45673009608e-09 -0.999999821186 +1.0 -7.15768493365e-08 +0.000427836901508 0.999999284744 +1.0 4.65823213336e-10 +8.19058811885e-08 0.999999642372 +1.0 1.43154829857e-05 +1.0 0.0 +1.0 -5.48225898456e-06 +7.07665822119e-05 -0.999999701977 +1.0 0.0 +0.00743747409433 -0.999972343445 +1.0 -2.18039508582e-06 +6.34209300188e-07 0.999999821186 +1.0 0.0 +7.54978799478e-08 1.0 +1.0 6.94411028235e-07 +1.0 8.39607025682e-07 +1.0 9.08725894533e-07 +1.0 5.94306072799e-07 +1.0 5.76279092002e-07 +1.0 1.59887955062e-14 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 6.85445211701e-09 +0.0179521366954 0.999838173389 +1.0 4.5159340516e-06 +1.0 2.67926825472e-05 +0.00231528375298 0.999997138977 +1.0 6.95042956522e-07 +1.0 7.73207830207e-07 +1.0 -3.53414179699e-06 +-1.40370293167e-08 -0.999999701977 +1.0 6.92014009473e-06 +1.0 -2.36670130107e-05 +1.0 1.88578455152e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +-0.000232024933212 -0.999999821186 +1.0 5.96130647068e-08 +0.000209049321711 0.999999821186 +1.0 0.0 +1.0 7.82466395322e-06 +1.0 1.19625238534e-11 +1.0 0.0 +1.0 -2.41921225097e-06 +-0.0938530638814 -0.995585680008 +1.0 0.0 +-0.00970268622041 -0.999952554703 +-0.999999403954 0.000938804645557 +-0.999999701977 -0.000227447773796 +1.0 4.98167409546e-08 +3.13916416417e-07 0.999999880791 +1.0 1.0783639226e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 1.0123632137e-06 +4.32983767951e-07 0.999999523163 +1.0 1.23870413518e-05 +1.0 1.28856161852e-11 +0.999999701977 -6.44184256089e-05 +0.999999821186 4.81020512311e-09 +0.999999523163 1.8377049571e-07 +0.999998509884 3.36233097187e-06 +-4.37113421015e-08 -0.999999701977 +-0.999999761581 1.38658649007e-07 +-0.999999463558 -1.51144547544e-06 +1.0 2.21665061417e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -3.96542162662e-07 +1.0 8.34396360005e-07 +5.37745791007e-06 0.999999940395 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 6.12346241269e-07 +1.0 2.6103930395e-06 +1.19246985619e-08 -0.999999940395 +1.0 1.74845553147e-07 +7.5238261843e-08 0.999999940395 +1.0 1.49814781025e-07 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -3.43536143976e-10 +1.0 1.36575999932e-06 +-3.69486059526e-08 0.999999880791 +1.0 6.32578394288e-06 +1.0 0.0 +1.94707240553e-07 -1.0 +1.0 -1.6652523982e-07 +1.0 0.0 +1.0 -1.15982066616e-13 +1.0 -2.94654932986e-06 +1.0 7.07389480326e-09 +1.18063523402e-08 -1.0 +-0.999999880791 4.68094822281e-06 +-0.999999821186 0.000217588691157 +-0.999999880791 0.000238092645304 +-0.999999880791 1.73171265487e-05 +-0.999999403954 0.000936420459766 +-0.999999701977 0.000617654295638 +1.0 6.67499250318e-11 +0.999999701977 0.000719422765542 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +4.97857690789e-05 -1.0 +1.0 -1.02379658529e-07 +0.99925673008 -0.038545653224 +1.0 -4.32282695328e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999999046326 -0.0013859824976 +0.999614477158 -0.0277643501759 +1.0 -2.94303748039e-11 +1.0 0.0 +1.0 0.0 +1.0 0.0 +0.999507963657 -0.0313648283482 +0.999999940395 -2.25276219901e-09 +-0.0605904757977 0.998161137104 +1.0 4.24349451578e-07 +1.0 0.0 +1.0 -5.61784418096e-07 +1.0 -1.41823800086e-14 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -6.0087103293e-08 +1.0 2.47721845881e-06 +1.0 1.40219401601e-06 +1.0 1.4936002799e-06 +1.0 1.82346468591e-06 +1.0 1.23531765439e-06 +1.0 1.29835643747e-06 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -4.4662083809e-08 +1.0 -5.1884343176e-13 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -2.3420640427e-10 +1.0 -4.44676429012e-09 +1.0 -1.57230033436e-14 +1.0 0.0 +1.0 0.0 +1.0 0.0 +1.0 -6.87038370639e-10 +1.0 9.10125322662e-07 +0.00317256059498 0.999994635582 +1.0 6.12572989667e-07 diff --git a/examples/core/maze/mazeFieldB.xml b/examples/core/maze/mazeFieldB.xml new file mode 100644 index 00000000..65d01cae --- /dev/null +++ b/examples/core/maze/mazeFieldB.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/maze/mazeMapB.xml b/examples/core/maze/mazeMapB.xml new file mode 100644 index 00000000..3b2624f3 --- /dev/null +++ b/examples/core/maze/mazeMapB.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/maze/mazeNMB.xml b/examples/core/maze/mazeNMB.xml new file mode 100644 index 00000000..9cf02351 --- /dev/null +++ b/examples/core/maze/mazeNMB.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/maze/mazeRoadmap.txt b/examples/core/maze/mazeRoadmap.txt new file mode 100644 index 00000000..a90deb27 --- /dev/null +++ b/examples/core/maze/mazeRoadmap.txt @@ -0,0 +1,527 @@ +260 +1 23.462500 25.668750 +3 23.350000 23.531250 +3 23.406250 20.606250 +1 15.418750 20.493750 +2 23.462500 18.693750 +3 21.437500 18.525000 +3 21.493750 16.725000 +2 13.506250 18.581250 +2 13.393750 21.393750 +1 4.618750 21.618750 +2 23.406250 16.556250 +2 9.568750 16.556250 +2 23.406250 8.625000 +3 20.481250 8.456250 +2 17.612500 8.568750 +3 17.387500 14.362500 +1 11.537500 14.643750 +1 19.468750 12.376875 +2 19.468750 10.655625 +2 21.341875 10.605000 +2 21.443125 14.401875 +3 20.531875 6.605625 +2 15.621250 6.706875 +1 15.418750 12.478125 +2 23.468125 6.453750 +1 23.468125 -4.329375 +2 9.596875 12.579375 +2 13.343125 12.478125 +2 13.545625 4.631250 +2 21.443125 4.530000 +3 21.341875 2.606250 +3 21.443125 -3.468750 +2 21.544375 -6.303750 +1 23.569375 -6.506250 +2 12.634375 -3.418125 +1 14.608750 -1.393125 +2 19.468750 -1.443750 +3 12.533125 0.429375 +2 19.367500 0.480000 +3 10.204375 0.429375 +1 7.318750 0.581250 +3 10.406875 -5.493750 +2 11.571250 2.555625 +1 11.470000 7.516875 +2 2.357500 23.463750 +2 2.458750 19.515000 +3 5.496250 19.464375 +3 7.420000 19.413750 +2 11.267500 19.464375 +1 11.470000 18.654375 +3 5.445625 8.529375 +1 0.433750 8.580000 +1 9.546250 8.529375 +2 7.369375 10.554375 +2 11.419375 10.554375 +1 11.419375 9.592500 +3 7.470625 -5.595000 +1 4.433125 -5.493750 +2 7.470625 -12.429375 +2 9.343750 -12.429375 +1 9.445000 -7.468125 +3 9.546250 -8.531250 +3 11.470000 -8.430000 +3 11.368750 -5.544375 +2 19.367500 -5.544375 +2 19.316875 -10.404375 +1 13.444375 -10.455000 +2 11.419375 -12.429375 +2 21.392500 -12.378750 +2 21.443125 -8.632500 +2 23.569375 -8.581875 +2 23.366875 -18.403125 +2 14.355625 -18.453750 +3 14.406250 -16.580625 +3 16.380625 -16.428750 +2 16.532500 -14.758125 +2 21.392500 -14.555625 +2 21.392500 -16.428750 +2 14.406250 -14.606250 +2 5.648125 -14.555625 +2 5.395000 -7.670625 +2 2.509375 -7.518750 +2 2.560000 -3.519375 +2 8.432500 -3.367500 +2 8.483125 -1.595625 +3 -0.376250 -1.393125 +1 -1.692500 -1.393125 +2 -0.477500 4.479375 +2 1.446250 4.479375 +2 1.446250 0.581250 +3 3.521875 0.631875 +1 5.395000 0.581250 +3 3.471250 2.454375 +2 9.394375 2.555625 +3 9.445000 4.580625 +1 7.420000 4.530000 +2 9.495625 6.504375 +2 5.496250 6.453750 +1 5.344375 4.428750 +2 3.420625 6.504375 +3 -1.591250 6.555000 +2 -1.641875 10.453125 +2 -8.476250 6.555000 +3 -8.526875 4.631250 +2 -8.577500 0.581250 +2 -2.502500 4.631250 +2 -2.553125 0.631875 +2 -4.628750 0.530625 +1 -4.476875 2.505000 +1 -6.552500 2.606250 +2 -6.653750 0.581250 +2 3.370000 10.554375 +2 3.420625 17.439375 +2 -1.439375 17.540625 +2 -1.490000 21.337500 +3 0.484375 21.438750 +1 0.535000 19.565625 +2 0.535000 23.463750 +2 -9.590000 23.413125 +3 -9.590000 17.591250 +1 -5.489375 17.641875 +2 -13.589375 17.490000 +3 -13.640000 15.515625 +1 -6.704375 15.515625 +3 -17.487500 15.465000 +2 -23.562500 15.465000 +2 -23.410625 18.451875 +4 -21.588125 18.553125 +1 -21.486875 17.490000 +2 -21.335000 20.375625 +2 -19.461875 18.451875 +2 -19.360625 17.540625 +2 -15.665000 17.490000 +3 -15.614375 19.464375 +2 -17.487500 19.413750 +1 -17.588750 20.476875 +2 -11.615000 19.565625 +2 -11.463125 21.438750 +1 -15.361250 21.641250 +2 -19.512500 20.527500 +3 -19.512500 22.501875 +3 -23.511875 22.501875 +1 -23.562500 23.463750 +1 -23.511875 20.628750 +2 -17.588750 22.603125 +2 -17.639375 23.413125 +1 -11.361875 23.514375 +3 -17.588750 13.642500 +3 -10.602500 13.440000 +1 -7.514375 13.591875 +2 -10.602500 11.617500 +2 -19.411250 11.465625 +2 -19.512500 6.504375 +2 -14.500625 6.504375 +3 -14.551250 -5.493750 +3 -16.576250 -5.392500 +3 -18.550625 -5.493750 +1 -19.613750 4.530000 +2 -16.525625 4.530000 +1 -18.500000 2.555625 +3 -20.423750 -5.392500 +3 -8.425625 -5.493750 +2 -8.526875 -1.443750 +2 -3.565625 -1.393125 +3 -3.413750 -3.367500 +1 -6.653750 -3.519375 +2 0.484375 -3.468750 +2 0.383125 -5.443125 +2 -20.575625 0.530625 +3 -20.575625 -7.366875 +2 -9.539375 -7.518750 +1 -9.691250 -15.466875 +2 -20.423750 -9.341250 +2 -11.615000 -9.594375 +3 -11.615000 -14.403750 +2 -11.513750 -17.390625 +3 -7.463750 -17.390625 +1 -6.451250 -17.441250 +2 -7.463750 -12.581250 +2 -2.502500 -12.429375 +2 -2.451875 -16.276875 +3 3.572500 -16.530000 +1 12.431875 -16.479375 +2 3.471250 -9.645000 +2 0.585625 -9.543750 +3 0.332500 -10.505625 +1 0.433750 -14.353125 +3 -6.603125 -10.353750 +1 -7.716875 -10.556250 +2 -6.451250 -8.480625 +2 -1.793750 -8.379375 +2 -1.439375 -7.518750 +1 0.383125 -7.417500 +2 -21.436250 0.682500 +3 -21.588125 5.593125 +1 -21.588125 11.566875 +3 -23.461250 5.593125 +2 -23.410625 13.490625 +2 -23.511875 -1.443750 +2 -22.651250 -1.494375 +3 -22.448750 -17.441250 +3 -22.550000 -19.415625 +1 -22.651250 -21.693750 +2 -17.538125 -19.466250 +3 -15.614375 -17.491875 +1 -15.513125 -13.593750 +2 -15.462500 -21.440625 +3 -17.487500 -23.415000 +1 -19.461875 -21.541875 +2 -19.563125 -23.415000 +2 -4.476875 -23.364375 +2 -6.653750 -21.390000 +2 -6.501875 -19.618125 +2 -13.589375 -19.365000 +3 -13.488125 -14.353125 +2 -13.589375 -11.467500 +3 -17.639375 -11.366250 +2 -17.639375 -15.365625 +2 -20.525000 -11.467500 +2 -20.423750 -15.517500 +3 -4.476875 -18.453750 +1 -4.476875 -14.606250 +2 12.431875 -18.352500 +3 12.482500 -23.465625 +3 10.356250 -23.415000 +2 10.406875 -20.529375 +2 4.433125 -20.529375 +2 4.433125 -21.491250 +2 -2.350625 -21.541875 +2 -2.451875 -23.364375 +2 23.468125 -23.415000 +2 23.468125 -20.630625 +1 14.406250 -20.529375 +1 -15.513125 8.934375 +2 -12.526250 8.478750 +2 -12.475625 2.606250 +3 -10.602500 2.555625 +1 -10.450625 9.440625 +2 -10.501250 -3.418125 +2 -12.475625 -3.418125 +1 -12.576875 0.480000 +1 -3.616250 8.630625 +2 -8.425625 8.630625 +2 -8.577500 11.313750 +3 -6.603125 11.566875 +2 -4.578125 11.516250 +1 -6.552500 10.756875 +1 -4.578125 10.706250 +3 -5.540000 11.617500 +2 -5.609201 13.431336 +2 -2.534051 13.455550 +2 -2.485623 12.562061 +2 1.371632 12.583854 +2 1.393424 15.504036 +3 -3.575243 15.482243 +1 -4.555902 15.504036 +2 -3.553451 21.453362 +2 -7.476083 21.496946 +2 -7.454291 19.644592 +1 -5.492975 19.557423 +264 +1 0 +2 1 +3 2 +4 2 +5 4 +6 5 +7 5 +8 7 +9 8 +10 6 +11 6 +12 10 +13 12 +14 13 +15 14 +16 15 +18 17 +19 18 +20 19 +20 15 +21 13 +22 21 +23 22 +24 21 +25 24 +26 11 +27 26 +28 27 +29 28 +30 29 +31 30 +32 31 +33 32 +34 31 +36 35 +37 34 +38 36 +38 37 +39 37 +40 39 +41 39 +42 30 +43 42 +44 1 +45 44 +46 45 +47 46 +48 47 +49 48 +50 46 +51 50 +52 50 +53 47 +54 53 +55 54 +56 41 +57 56 +58 56 +59 58 +61 59 +60 61 +62 61 +63 62 +41 63 +67 62 +63 64 +64 65 +65 66 +67 68 +69 68 +69 70 +71 70 +72 71 +73 72 +74 73 +75 74 +76 75 +77 74 +76 77 +78 73 +79 78 +80 79 +81 80 +82 81 +83 82 +84 83 +85 84 +86 85 +87 85 +88 87 +89 88 +90 89 +91 90 +92 90 +93 92 +94 93 +95 94 +96 94 +97 96 +98 97 +99 92 +100 99 +101 100 +102 100 +103 102 +104 103 +105 103 +106 105 +107 106 +108 107 +110 104 +109 110 +111 101 +112 111 +113 112 +114 113 +115 114 +116 115 +117 115 +118 117 +119 118 +120 119 +121 119 +122 121 +123 122 +124 122 +125 124 +126 125 +127 126 +128 127 +129 127 +130 127 +131 130 +132 131 +133 132 +134 133 +135 134 +136 133 +137 136 +138 137 +139 129 +140 139 +141 140 +142 141 +143 141 +144 140 +145 144 +146 145 +147 124 +148 147 +149 148 +150 148 +151 150 +152 151 +153 152 +154 153 +155 154 +156 155 +158 155 +158 157 +159 156 +160 156 +161 154 +162 161 +163 162 +164 163 +165 164 +166 164 +167 166 +167 161 +168 160 +169 160 +170 169 +171 170 +172 169 +173 172 +174 173 +175 174 +176 175 +177 176 +178 176 +179 178 +180 179 +181 180 +182 181 +183 181 +184 183 +185 184 +186 185 +187 185 +188 187 +189 187 +190 189 +191 190 +192 191 +193 168 +194 193 +195 194 +196 194 +197 196 +147 197 +198 196 +199 198 +200 199 +201 200 +202 201 +203 201 +204 200 +205 204 +206 204 +207 203 +209 207 +209 208 +210 207 +211 206 +212 211 +213 212 +214 213 +214 174 +215 214 +216 215 +217 216 +218 216 +219 217 +218 219 +220 210 +221 220 +222 220 +223 222 +224 223 +225 224 +226 225 +227 226 +228 227 +229 228 +229 224 +230 223 +231 230 +232 231 +234 233 +235 234 +236 235 +237 236 +238 236 +239 238 +240 239 +242 241 +243 242 +244 243 +246 244 +247 245 +248 244 +248 245 +249 248 +251 250 +249 250 +252 251 +253 252 +254 253 +255 254 +256 254 +257 256 +258 257 +259 258 + diff --git a/examples/core/maze/mazeS.xml b/examples/core/maze/mazeS.xml new file mode 100644 index 00000000..bed91082 --- /dev/null +++ b/examples/core/maze/mazeS.xml @@ -0,0 +1,609 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/maze/mazeV.xml b/examples/core/maze/mazeV.xml new file mode 100644 index 00000000..a6465365 --- /dev/null +++ b/examples/core/maze/mazeV.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/core/navMesh.xml b/examples/core/navMesh.xml new file mode 100644 index 00000000..0719c3e8 --- /dev/null +++ b/examples/core/navMesh.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/navMesh/navMeshB.xml b/examples/core/navMesh/navMeshB.xml new file mode 100644 index 00000000..223f6c8e --- /dev/null +++ b/examples/core/navMesh/navMeshB.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/navMesh/navMeshS.xml b/examples/core/navMesh/navMeshS.xml new file mode 100644 index 00000000..cd1bbc32 --- /dev/null +++ b/examples/core/navMesh/navMeshS.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/navMesh/navMeshV.xml b/examples/core/navMesh/navMeshV.xml new file mode 100644 index 00000000..38c43082 --- /dev/null +++ b/examples/core/navMesh/navMeshV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/navMesh/simple.nav b/examples/core/navMesh/simple.nav new file mode 100644 index 00000000..557c82cd --- /dev/null +++ b/examples/core/navMesh/simple.nav @@ -0,0 +1,89 @@ +13 +-5.0 6.0 +-1.0 6.0 +1.0 6.0 +3.0 6.0 +-5.0 3.0 +-1.0 3.0 +1.0 3.0 +3.0 3.0 +-1.0 0.0 +1.0 0.0 +-1.0 -3.0 +1.0 -3.0 +0.0 1.5 + +7 + 1 5 0 1 + 2 6 1 2 + 5 6 1 3 + 8 9 6 7 + 5 12 3 5 + 6 12 3 4 + 9 12 4 6 + +13 + 0 1 0 1 + 1 2 1 2 + 2 3 2 3 + 3 7 2 4 + 7 6 2 5 + 6 9 4 6 + 9 11 7 7 + 11 10 7 8 + 10 8 7 9 + 8 5 5 10 + 5 4 0 11 + 4 0 0 0 + 8 12 5 -1 + +nodeGroup +8 + -3.0 4.50 + 4 4 5 1 0 + 0 0 1.0 + 1 0 + 5 0 1 11 10 9 + + 0.0 4.50 + 4 5 6 2 1 + 0 0 1.0 + 3 0 1 2 + 7 0 1 2 4 5 9 10 + + 2.00 4.50 + 4 6 7 3 2 + 0 0 1.0 + 1 1 + 5 1 2 3 4 5 + + 0.0 2.50 + 3 12 6 5 + 0.0 0.33333 0.0 + 3 2 4 5 + 5 4 5 9 10 12 + + 0.5 1.50 + 3 12 9 6 + 0.0 0.33333 0.0 + 2 5 6 + 4 4 5 6 12 + + -0.5 1.50 + 3 12 5 8 + 0.0 0.33333 0.0 + 1 4 + 3 9 10 12 + + 0.0 0.75 + 3 12 8 9 + 0.0 0.33333 0.0 + 2 3 6 + 4 5 6 8 12 + + 0.0 -1.50 + 4 10 11 9 8 + 0.0 0.0 0.0 + 1 3 + 5 5 6 7 8 9 + \ No newline at end of file diff --git a/examples/core/obstacleSwitch.xml b/examples/core/obstacleSwitch.xml new file mode 100644 index 00000000..fcba11f7 --- /dev/null +++ b/examples/core/obstacleSwitch.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/obstacleSwitch/obstacleSwitchB.xml b/examples/core/obstacleSwitch/obstacleSwitchB.xml new file mode 100644 index 00000000..547ce0d9 --- /dev/null +++ b/examples/core/obstacleSwitch/obstacleSwitchB.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/obstacleSwitch/obstacleSwitchS.xml b/examples/core/obstacleSwitch/obstacleSwitchS.xml new file mode 100644 index 00000000..b5aac554 --- /dev/null +++ b/examples/core/obstacleSwitch/obstacleSwitchS.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/obstacleSwitch/obstacleSwitchV.xml b/examples/core/obstacleSwitch/obstacleSwitchV.xml new file mode 100644 index 00000000..57633737 --- /dev/null +++ b/examples/core/obstacleSwitch/obstacleSwitchV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/office.xml b/examples/core/office.xml new file mode 100644 index 00000000..4aacc9ec --- /dev/null +++ b/examples/core/office.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/office/graph.txt b/examples/core/office/graph.txt new file mode 100644 index 00000000..9860857e --- /dev/null +++ b/examples/core/office/graph.txt @@ -0,0 +1,491 @@ +237 +2 -6.259497 0.724659 +2 -3.790624 0.686997 +2 -0.601940 0.706494 +2 -0.566196 2.194326 +2 -0.557302 4.729874 +3 -0.857288 7.193728 +2 -1.845703 7.372118 +4 -2.875927 7.401139 +4 -4.950967 7.454918 +2 -20.651415 0.813336 +2 -26.165435 0.842357 +3 -26.165435 2.264394 +2 -25.831848 6.334138 +3 -25.831415 7.479323 +4 -23.789118 7.438435 +4 -21.625003 7.438435 +2 -24.424166 2.264394 +2 -20.537584 2.293415 +2 -34.918086 2.322436 +2 -32.172816 2.293415 +2 -29.183636 2.322436 +2 -29.212657 3.802515 +2 -29.241678 5.543785 +3 -29.308838 7.507660 +2 -30.573997 7.507470 +4 -31.460959 7.505176 +4 -33.613209 7.505176 +1 -33.613209 6.063420 +2 -2.885768 5.690273 +2 -2.921620 3.861777 +2 -6.542759 3.915556 +2 -9.644032 3.951409 +2 -11.759351 3.951409 +2 -11.759351 5.744052 +3 -11.741424 7.339505 +2 -10.522427 7.518769 +4 -9.626105 7.500843 +1 -9.626105 5.887464 +1 -9.590253 8.988736 +4 -8.568446 7.500843 +1 -8.550520 8.952883 +1 -8.604299 5.905390 +2 -7.510787 7.518769 +4 -6.076672 7.536695 +1 -6.040819 8.952883 +1 -6.094599 5.905390 +1 -4.947307 8.917031 +1 -5.001086 5.995022 +2 -2.885768 9.365191 +2 -2.903694 11.139908 +4 -2.903694 12.914625 +2 -11.741424 9.060442 +2 -11.741424 10.960644 +3 -11.723498 12.807066 +2 -10.486574 12.807066 +1 -9.572326 11.301246 +4 -9.518547 12.753287 +1 -9.554400 14.330812 +1 -8.532593 14.348739 +4 -8.550520 12.807066 +1 -8.532593 11.265393 +2 -7.367375 12.842919 +2 -6.453127 12.842919 +4 -6.058746 12.824992 +1 -6.058746 11.319172 +1 -6.040819 14.330812 +1 -5.019013 11.283319 +1 -5.054866 14.348739 +4 -5.036939 12.860845 +2 -3.961353 12.878772 +2 -2.903694 14.492150 +2 -2.903694 15.782853 +2 -2.903694 16.715028 +2 -4.588778 16.715028 +2 -6.381422 16.697101 +2 -8.425035 16.697101 +2 -10.558280 16.679175 +2 -11.759351 16.661248 +2 -11.723498 15.370545 +2 -11.723498 14.115695 +2 -0.967640 8.612281 +2 -0.967640 10.458704 +4 -0.967640 12.824992 +1 2.510088 12.699507 +2 -0.967640 14.366665 +2 -0.985566 16.392352 +2 -0.985566 20.085197 +3 -0.985566 19.045464 +2 -2.025299 19.063390 +3 -2.509313 19.081317 +1 -2.527239 17.987804 +1 -3.620751 17.987804 +3 -3.620751 19.063390 +1 -4.642558 18.005731 +2 -4.624631 19.045464 +1 -4.606705 22.343927 +1 -3.602825 22.361853 +1 -2.491386 22.361853 +3 -2.509313 21.375900 +3 -3.566972 21.393826 +2 -4.606705 21.375900 +3 -0.949713 21.393826 +2 -0.519479 22.272221 +2 -0.519479 23.562924 +2 -0.537405 25.050818 +2 -1.899814 24.993420 +2 -6.214822 25.050818 +2 -20.617733 24.999727 +2 -21.738261 25.030853 +2 -23.107795 25.030853 +2 -24.570707 24.999727 +2 -26.158122 25.030853 +2 -26.220374 24.252708 +3 -26.251500 23.443438 +2 -26.207021 22.065017 +3 -25.833422 20.713256 +2 -25.037594 23.524069 +2 -23.885940 23.529702 +2 -22.796538 23.542448 +2 -21.644884 23.536815 +2 -20.424442 23.536815 +2 -33.547600 23.534626 +2 -32.480121 23.556866 +2 -31.546076 23.534626 +2 -29.166487 23.534626 +2 -34.897372 23.534626 +2 -29.188726 21.977886 +3 -29.233204 20.287710 +6 -30.856663 20.265471 +1 -31.012337 21.444146 +1 -31.056815 18.619774 +1 -32.546838 18.642013 +1 -32.702512 21.711016 +1 -32.658034 20.220993 +2 -29.366639 18.019317 +3 -25.808375 19.286948 +3 -24.763135 20.132036 +2 -23.384307 20.109797 +1 -21.360544 20.132036 +2 -25.830614 17.240946 +2 -25.808375 14.327617 +3 -25.808375 12.815355 +4 -23.829090 12.793116 +2 -25.830614 10.813831 +2 -25.830614 8.678872 +2 -26.119723 3.541628 +2 -25.786136 4.364477 +2 -23.806851 14.394335 +2 -23.806851 16.553823 +2 -29.388879 16.062271 +2 -29.500074 14.461052 +3 -29.516864 12.883399 +2 -21.526070 16.564342 +2 -14.895223 16.564342 +2 -16.321909 16.548130 +3 -14.895223 12.948990 +4 -16.986615 12.965202 +4 -18.007992 12.948990 +4 -21.623345 12.965202 +1 -21.607132 14.343251 +1 -21.639557 11.246694 +1 -20.585755 14.505375 +1 -20.601967 11.295331 +1 -18.007992 14.343251 +1 -17.991780 11.295331 +1 -16.970402 14.391888 +1 -16.970402 11.279119 +2 -23.819645 5.298900 +2 -23.763148 11.345819 +2 -23.826707 9.407274 +2 -23.826707 3.814094 +2 -22.158287 3.814094 +2 -16.072526 3.829984 +2 -14.737789 3.814094 +2 -14.753679 5.228279 +3 -14.753679 7.325721 +2 -14.896686 11.028025 +2 -14.896686 8.962362 +2 -15.786511 7.421059 +4 -17.057688 7.436949 +4 -18.026961 7.421059 +2 -19.377587 7.421059 +4 -20.601095 7.436949 +1 -21.633926 5.975095 +1 -21.633926 9.025921 +1 -20.616984 9.025921 +1 -20.616984 5.879757 +1 -18.026961 9.010031 +1 -18.011071 5.832088 +1 -17.073578 8.994141 +1 -17.041798 5.816198 +4 -20.590033 12.961171 +2 -19.284915 12.935580 +4 -34.642806 7.518284 +1 -34.659596 6.040767 +1 -33.601829 8.945430 +1 -34.642806 8.962220 +2 -35.918843 7.518284 +4 -37.228459 7.518284 +1 -37.211670 8.794321 +1 -37.228459 5.990398 +1 -38.202277 6.023978 +1 -38.168697 8.794321 +4 -38.185487 7.501494 +3 -40.384972 7.501494 +2 -31.469504 5.419539 +2 -31.469504 3.874863 +2 -32.695171 3.891653 +2 -38.974615 3.908443 +2 -40.384972 3.891653 +2 -40.384972 5.083740 +2 -40.384972 9.549869 +2 -40.368182 11.497504 +3 -40.351392 12.924650 +4 -38.202277 12.941440 +4 -37.245249 12.958230 +2 -35.986003 12.941440 +4 -34.626016 12.941440 +4 -33.517879 12.941440 +1 -33.517879 14.251057 +1 -33.534669 11.430344 +1 -34.626016 11.430344 +1 -34.642806 14.385377 +1 -37.228459 11.396764 +1 -37.245249 14.368587 +1 -38.219067 11.329604 +1 -38.185487 14.368587 +2 -31.452714 9.348389 +2 -31.452714 11.312814 +4 -31.469504 12.941440 +2 -29.421129 10.557266 +2 -31.450653 15.318373 +2 -31.478099 16.526020 +2 -40.370772 15.236033 +2 -40.398218 16.526020 +2 -39.272911 16.498573 +2 -32.575960 16.526020 +251 +1 0 +2 1 +3 2 +4 3 +5 4 +6 5 +7 6 +8 7 +10 9 +11 10 +14 13 +13 12 +15 14 +0 9 +16 11 +17 16 +18 17 +19 18 +20 19 +21 20 +22 21 +23 22 +24 23 +25 24 +26 25 +27 26 +28 7 +29 28 +30 29 +31 30 +32 31 +33 32 +34 33 +35 34 +36 35 +37 36 +38 36 +40 39 +36 39 +41 39 +42 39 +43 42 +44 43 +45 43 +43 8 +46 8 +47 8 +48 7 +49 48 +50 49 +51 34 +52 51 +53 52 +54 53 +57 56 +55 56 +54 56 +59 58 +60 59 +56 59 +61 59 +62 61 +63 62 +64 63 +65 63 +68 67 +66 68 +63 68 +69 68 +50 69 +70 50 +71 70 +72 71 +73 72 +74 73 +75 74 +76 75 +77 76 +78 77 +79 53 +78 79 +80 5 +81 80 +82 81 +83 82 +50 82 +84 82 +85 84 +87 86 +85 87 +88 87 +89 88 +90 89 +92 89 +91 92 +94 92 +93 94 +98 97 +99 98 +99 96 +100 99 +100 95 +101 98 +101 86 +102 101 +103 102 +104 103 +105 104 +108 107 +109 108 +110 109 +111 110 +107 106 +112 111 +113 112 +114 113 +115 114 +116 113 +117 116 +118 117 +119 118 +120 119 +122 121 +123 122 +123 124 +125 121 +125 120 +126 124 +127 126 +128 127 +129 128 +130 128 +131 128 +132 128 +133 128 +134 127 +135 115 +136 135 +136 115 +137 136 +138 137 +139 135 +140 139 +141 140 +142 141 +143 141 +144 143 +13 144 +145 11 +146 145 +12 146 +147 142 +148 147 +149 134 +150 149 +151 150 +152 148 +154 153 +154 152 +155 153 +156 155 +157 156 +142 158 +159 158 +160 158 +163 157 +164 157 +165 156 +166 156 +167 14 +168 142 +169 168 +14 169 +170 167 +171 170 +172 171 +173 172 +174 173 +175 174 +176 155 +177 176 +177 175 +178 175 +179 178 +180 179 +181 180 +182 181 +15 182 +183 15 +184 15 +185 182 +186 182 +187 180 +188 180 +189 179 +190 179 +192 157 +191 192 +191 161 +162 191 +158 191 +193 26 +194 193 +195 26 +196 193 +197 193 +198 197 +199 198 +200 198 +203 198 +202 203 +201 203 +204 203 +205 25 +206 205 +207 206 +208 207 +209 208 +210 209 +204 210 +211 204 +213 212 +212 211 +214 213 +215 214 +216 215 +217 216 +218 217 +219 218 +220 218 +221 217 +222 217 +223 215 +224 215 +225 214 +226 214 +227 25 +228 227 +229 228 +218 229 +151 229 +230 151 +23 230 +231 229 +232 231 +233 213 +234 233 +235 234 +236 232 +235 236 +105 106 + diff --git a/examples/core/office/officeB.xml b/examples/core/office/officeB.xml new file mode 100644 index 00000000..4669ec03 --- /dev/null +++ b/examples/core/office/officeB.xml @@ -0,0 +1,357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/core/office/officeS.xml b/examples/core/office/officeS.xml new file mode 100644 index 00000000..a8393549 --- /dev/null +++ b/examples/core/office/officeS.xml @@ -0,0 +1,721 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/office/officeV.xml b/examples/core/office/officeV.xml new file mode 100644 index 00000000..112936ff --- /dev/null +++ b/examples/core/office/officeV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/pedModelSwap.xml b/examples/core/pedModelSwap.xml new file mode 100644 index 00000000..87acb03c --- /dev/null +++ b/examples/core/pedModelSwap.xml @@ -0,0 +1,12 @@ + + + diff --git a/examples/core/pedModelSwap/pedModelSwapB.xml b/examples/core/pedModelSwap/pedModelSwapB.xml new file mode 100644 index 00000000..169bac4b --- /dev/null +++ b/examples/core/pedModelSwap/pedModelSwapB.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/pedModelSwap/pedModelSwapS.xml b/examples/core/pedModelSwap/pedModelSwapS.xml new file mode 100644 index 00000000..6b564637 --- /dev/null +++ b/examples/core/pedModelSwap/pedModelSwapS.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/pedModelSwap/pedModelSwapV.xml b/examples/core/pedModelSwap/pedModelSwapV.xml new file mode 100644 index 00000000..ce2d2320 --- /dev/null +++ b/examples/core/pedModelSwap/pedModelSwapV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/periodic.xml b/examples/core/periodic.xml new file mode 100644 index 00000000..1614e17f --- /dev/null +++ b/examples/core/periodic.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/periodic/periodicB.xml b/examples/core/periodic/periodicB.xml new file mode 100644 index 00000000..1d90d444 --- /dev/null +++ b/examples/core/periodic/periodicB.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/periodic/periodicS.xml b/examples/core/periodic/periodicS.xml new file mode 100644 index 00000000..8ce06767 --- /dev/null +++ b/examples/core/periodic/periodicS.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/periodic/periodicV.xml b/examples/core/periodic/periodicV.xml new file mode 100644 index 00000000..2c6b88bb --- /dev/null +++ b/examples/core/periodic/periodicV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/persistGoal.xml b/examples/core/persistGoal.xml new file mode 100644 index 00000000..43832b25 --- /dev/null +++ b/examples/core/persistGoal.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/persistGoal/persistGoalB.xml b/examples/core/persistGoal/persistGoalB.xml new file mode 100644 index 00000000..854865a0 --- /dev/null +++ b/examples/core/persistGoal/persistGoalB.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/persistGoal/persistGoalS.xml b/examples/core/persistGoal/persistGoalS.xml new file mode 100644 index 00000000..6ada8937 --- /dev/null +++ b/examples/core/persistGoal/persistGoalS.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/persistGoal/persistGoalV.xml b/examples/core/persistGoal/persistGoalV.xml new file mode 100644 index 00000000..66aa3071 --- /dev/null +++ b/examples/core/persistGoal/persistGoalV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/randomGoal.xml b/examples/core/randomGoal.xml new file mode 100644 index 00000000..1031f0f9 --- /dev/null +++ b/examples/core/randomGoal.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/randomGoal/randomGoalB.xml b/examples/core/randomGoal/randomGoalB.xml new file mode 100644 index 00000000..64bc9fd7 --- /dev/null +++ b/examples/core/randomGoal/randomGoalB.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/randomGoal/randomGoalS.xml b/examples/core/randomGoal/randomGoalS.xml new file mode 100644 index 00000000..f6e975d8 --- /dev/null +++ b/examples/core/randomGoal/randomGoalS.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/randomGoal/randomGoalV.xml b/examples/core/randomGoal/randomGoalV.xml new file mode 100644 index 00000000..83060f43 --- /dev/null +++ b/examples/core/randomGoal/randomGoalV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/sharedGoal.xml b/examples/core/sharedGoal.xml new file mode 100644 index 00000000..14488c80 --- /dev/null +++ b/examples/core/sharedGoal.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/sharedGoal/scene.nav b/examples/core/sharedGoal/scene.nav new file mode 100644 index 00000000..23a4d686 --- /dev/null +++ b/examples/core/sharedGoal/scene.nav @@ -0,0 +1,138 @@ +21 + -1.03744 1.59241 + -0.07917 -1.70924 + 3.89856 1.59241 + 3.06479 -1.70924 + 4.73233 -1.70924 + 12.00884 1.59241 + 9.26924 -1.70924 + -1.03744 -5.73676 + -0.07917 -5.73676 + 3.06479 -5.73676 + 4.73233 -5.73676 + 9.26924 -5.73676 + 12.00884 -8.42083 + -0.55831 -8.42083 + 3.89856 -8.42083 + -2.07151 -5.73676 + -2.07151 -8.42083 + -2.78706 -4.09335 + -2.78706 -9.66587 + -5.71950 -4.09335 + -5.71950 -9.66587 +14 + 8 13 6 8 + 5 6 2 5 + 15 16 10 11 + 9 14 7 8 + 9 10 4 7 + 2 3 0 1 + 17 18 11 12 + 11 12 5 9 + 0 1 0 3 + 3 4 1 4 + 7 13 6 10 + 10 14 7 9 + 7 8 3 6 + 2 4 1 2 +21 + 3 1 0 20 + 7 0 3 18 + 8 9 8 14 + 10 11 9 13 + 2 5 2 7 + 15 7 10 1 + 20 19 12 11 + 5 12 5 12 + 13 16 10 9 + 16 18 11 19 + 4 10 4 3 + 19 17 12 15 + 12 14 9 17 + 11 6 5 16 + 9 3 4 0 + 17 15 11 5 + 6 4 2 10 + 14 13 8 8 + 0 2 0 4 + 18 20 12 6 + 1 8 3 2 +defaultGrp +13 + 1.46168 -0.05841 + 4 1 0 2 3 + 0.00000 0.00000 0.00000 + 2 5 8 + 6 1 18 0 20 4 14 + + 3.89856 -0.60869 + 3 3 2 4 + 0.00000 0.00000 0.00000 + 3 5 9 13 + 6 4 18 0 14 10 16 + + 7.47724 -0.05841 + 4 4 2 5 6 + 0.00000 0.00000 0.00000 + 2 1 13 + 6 4 18 10 16 7 13 + + -0.55831 -2.89759 + 4 0 1 8 7 + 0.00000 0.00000 0.00000 + 2 8 12 + 6 1 18 0 20 5 2 + + 3.89856 -3.72300 + 4 3 4 10 9 + 0.00000 0.00000 0.00000 + 2 4 9 + 6 0 14 10 16 2 3 + + 10.63904 -3.56860 + 4 6 5 12 11 + 0.00000 0.00000 0.00000 + 2 1 7 + 6 4 7 13 16 3 12 + + -0.55831 -6.63145 + 3 7 8 13 + -0.00000 -0.00000 0.00000 + 3 0 10 12 + 6 1 5 2 20 8 17 + + 3.89856 -6.63145 + 3 9 10 14 + 0.00000 -0.00000 0.00000 + 3 3 4 11 + 6 2 14 3 10 12 17 + + 1.58147 -7.07879 + 4 13 8 9 14 + 0.00000 0.00000 0.00000 + 2 0 3 + 6 2 20 14 8 17 12 + + 7.47724 -7.07879 + 4 14 10 11 12 + 0.00000 0.00000 0.00000 + 2 7 11 + 6 3 10 13 7 12 17 + + -1.43469 -7.07879 + 4 7 13 16 15 + 0.00000 0.00000 0.00000 + 2 2 10 + 6 1 5 8 17 15 9 + + -2.42929 -6.97920 + 4 15 16 18 17 + 0.00000 0.00000 0.00000 + 2 2 6 + 6 5 15 8 9 11 19 + + -4.25328 -6.87961 + 4 17 18 20 19 + 0.00000 0.00000 0.00000 + 1 6 + 5 11 15 9 19 6 diff --git a/examples/core/sharedGoal/sharedGoalB.xml b/examples/core/sharedGoal/sharedGoalB.xml new file mode 100644 index 00000000..f386269b --- /dev/null +++ b/examples/core/sharedGoal/sharedGoalB.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/sharedGoal/sharedGoalS.xml b/examples/core/sharedGoal/sharedGoalS.xml new file mode 100644 index 00000000..73de4b51 --- /dev/null +++ b/examples/core/sharedGoal/sharedGoalS.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/sharedGoal/sharedGoalV.xml b/examples/core/sharedGoal/sharedGoalV.xml new file mode 100644 index 00000000..6393cc65 --- /dev/null +++ b/examples/core/sharedGoal/sharedGoalV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/examples/core/soccer.xml b/examples/core/soccer.xml new file mode 100644 index 00000000..2fbb774b --- /dev/null +++ b/examples/core/soccer.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/soccer/soccer.nav b/examples/core/soccer/soccer.nav new file mode 100644 index 00000000..61e65872 --- /dev/null +++ b/examples/core/soccer/soccer.nav @@ -0,0 +1,1217 @@ +212 + -1.20028 8.14382 + -2.40056 8.14382 + -1.20028 7.54990 + -2.40056 7.54990 + -1.20028 7.34382 + -2.40056 7.34382 + -1.20028 6.74990 + -2.40057 6.74990 + -1.20028 6.54382 + -2.40057 6.54382 + -1.20028 5.94990 + -2.40057 5.94990 + -1.20028 5.74382 + -2.40057 5.74382 + -1.20028 5.14990 + -2.40057 5.14990 + -1.20028 4.94382 + -2.40057 4.94382 + -1.20028 4.34990 + -2.40057 4.34990 + -1.20057 4.14382 + -2.40057 4.14382 + -1.20057 3.54990 + -2.40057 3.54990 + -1.20057 3.34382 + -2.40057 3.34382 + -1.20057 2.74990 + -2.40057 2.74990 + -1.20057 2.54382 + -2.40057 2.54382 + -1.20057 1.94990 + -2.40057 1.94990 + -1.20057 1.74382 + -2.40057 1.74382 + -1.20057 1.14990 + -2.40057 1.14990 + -1.20057 0.94382 + -2.40057 0.94382 + -1.20057 0.34990 + -2.40057 0.34990 + -1.20057 0.14383 + -2.40057 0.14383 + -1.20057 -0.45365 + -2.40057 -0.45365 + -10.00055 8.14382 + -10.00056 7.54990 + -10.00056 7.34382 + -10.00056 6.74990 + -10.00056 6.54382 + -10.00056 5.94990 + -10.00056 5.74382 + -10.00056 5.14990 + -10.00056 4.94382 + -10.00056 4.34990 + -10.00056 4.14382 + -10.00056 3.54990 + -10.00056 3.34382 + -10.00056 2.74990 + -10.00056 2.54382 + -10.00056 1.94990 + -10.00056 1.74382 + -10.00056 1.14990 + -10.00056 0.94382 + -10.00056 0.34990 + -10.00056 0.14383 + -10.00056 -0.45365 + -0.20056 3.34382 + -0.20056 2.74990 + -0.20056 2.54382 + -0.20056 1.94990 + -0.20056 1.74382 + -0.20056 1.14990 + -0.20056 0.94382 + -0.20056 0.34990 + -2.40057 -1.25365 + -1.20057 -1.25365 + 0.59972 -0.18667 + 0.59945 -1.25365 + -1.20057 0.34635 + 0.00383 0.34635 + -2.40057 -0.64253 + -3.20127 -0.64253 + -3.20127 -1.25365 + -10.00056 -0.64253 + -10.00056 -1.25365 + 0.59972 -3.65365 + 0.59972 -1.45526 + 0.59972 -2.02313 + 0.59972 -2.22830 + 0.59972 -2.82430 + 0.59972 -3.01893 + -10.00056 -1.45526 + -10.00056 -2.02313 + -10.00056 -2.22830 + -10.00056 -2.82430 + -10.00056 -3.01893 + -10.00056 -3.65365 + 3.60000 8.14382 + 4.80000 8.14382 + 3.60000 7.54990 + 4.80000 7.54990 + 3.60001 7.34382 + 4.80001 7.34382 + 3.60001 6.74990 + 4.80001 6.74990 + 3.60001 6.54382 + 4.80001 6.54382 + 3.60001 5.94990 + 4.80001 5.94990 + 3.60001 5.74382 + 4.80001 5.74382 + 3.60001 5.14990 + 4.80001 5.14990 + 3.60001 4.94382 + 4.80001 4.94382 + 3.60001 4.34990 + 4.80001 4.34990 + 3.60001 4.14382 + 4.80001 4.14382 + 3.60001 3.54990 + 4.80001 3.54990 + 3.60001 3.34382 + 4.80001 3.34382 + 3.60001 2.74990 + 4.80001 2.74990 + 3.60001 2.54382 + 4.80001 2.54382 + 3.60001 1.94990 + 4.80001 1.94990 + 3.60001 1.74382 + 4.80001 1.74382 + 3.60001 1.14990 + 4.80001 1.14990 + 3.60001 0.94382 + 4.80001 0.94382 + 3.60001 0.34990 + 4.80001 0.34990 + 3.60001 0.14383 + 4.80001 0.14383 + 3.60001 -0.45365 + 4.80001 -0.45365 + 12.39999 8.14382 + 12.40000 7.54990 + 12.40000 7.34382 + 12.40000 6.74990 + 12.40000 6.54382 + 12.40000 5.94990 + 12.40000 5.74382 + 12.40001 5.14990 + 12.40001 4.94382 + 12.40001 4.34990 + 12.40001 4.14382 + 12.40001 3.54990 + 12.40001 3.34382 + 12.40001 2.74990 + 12.40001 2.54382 + 12.40001 1.94990 + 12.40001 1.74382 + 12.40001 1.14990 + 12.40001 0.94382 + 12.40001 0.34990 + 12.40001 0.14383 + 12.40001 -0.45365 + 2.60000 3.34382 + 2.60000 2.74990 + 2.60000 2.54382 + 2.60001 1.94990 + 2.60001 1.74382 + 2.60001 1.14990 + 2.60001 0.94382 + 2.60001 0.34990 + 4.80001 -1.25365 + 3.60001 -1.25365 + 1.80000 -0.18667 + 1.80000 -1.25365 + 3.60001 0.34635 + 2.39561 0.34635 + 2.39561 8.14635 + 0.00383 8.14635 + 13.18958 10.42795 + -10.79013 10.42795 + 13.18958 20.51819 + -10.79013 20.51819 + 4.80001 -0.64253 + 5.60072 -0.64253 + 5.60072 -1.25365 + 12.40000 -0.64253 + 12.40000 -1.25365 + 1.80000 -3.65365 + 1.80000 -1.45526 + 1.80000 -2.02313 + 1.80000 -2.22830 + 1.80000 -2.82430 + 1.80000 -3.01893 + 12.40000 -1.45526 + 12.40000 -2.02313 + 12.40000 -2.22830 + 12.40000 -2.82430 + 12.40000 -3.01893 + 12.40000 -3.65365 + 1.19972 3.54990 + 1.19972 4.14382 + 1.19972 4.34990 + 1.19972 4.94382 + 1.19972 5.14990 + 1.19972 5.74382 + 1.19972 5.94990 + 1.19972 6.54382 + 1.19972 6.74990 + 1.19987 7.34382 + 1.19986 7.54990 + 1.19986 8.14382 +117 + 87 190 98 99 + 37 39 18 30 + 125 126 58 59 + 200 201 82 106 + 101 102 46 47 + 106 108 49 68 + 40 41 19 20 + 18 19 8 9 + 127 128 59 60 + 184 185 95 96 + 6 7 2 3 + 115 116 53 54 + 28 29 13 14 + 42 76 37 38 + 85 90 44 102 + 4 5 1 2 + 177 178 91 92 + 122 124 57 72 + 105 106 48 49 + 191 192 100 104 + 14 15 6 7 + 139 173 88 89 + 107 108 49 50 + 109 110 50 51 + 99 100 45 46 + 32 34 16 34 + 117 118 54 55 + 188 193 102 105 + 110 112 51 69 + 131 132 61 62 + 114 116 53 70 + 22 23 10 11 + 129 131 61 85 + 13 15 6 24 + 8 9 3 4 + 17 19 8 25 + 138 140 65 76 + 139 172 87 88 + 134 136 63 75 + 12 13 5 6 + 41 43 20 31 + 126 128 59 73 + 103 104 47 48 + 32 33 15 16 + 206 207 79 109 + 118 120 55 71 + 139 140 65 94 + 36 38 18 35 + 208 209 78 110 + 86 189 97 98 + 38 39 18 19 + 4 6 2 110 + 74 80 36 40 + 5 7 2 22 + 130 132 61 74 + 24 25 11 12 + 81 82 40 41 + 0 2 0 111 + 34 35 16 17 + 1 3 0 21 + 42 43 20 39 + 210 211 77 111 + 133 135 63 86 + 36 37 17 18 + 171 183 87 95 + 113 115 53 81 + 12 14 6 108 + 16 17 7 8 + 102 104 47 67 + 139 183 87 94 + 101 103 47 78 + 8 10 4 109 + 173 176 89 90 + 133 134 62 63 + 9 11 4 23 + 117 119 55 82 + 204 205 80 108 + 20 22 10 106 + 42 80 36 39 + 21 23 10 26 + 121 123 57 83 + 2 3 0 1 + 119 120 55 56 + 76 79 38 90 + 42 75 36 37 + 125 127 59 84 + 97 99 45 77 + 30 31 14 15 + 135 136 63 64 + 10 11 4 5 + 113 114 52 53 + 24 26 12 32 + 111 112 51 52 + 25 27 12 27 + 90 193 101 102 + 129 130 60 61 + 121 122 56 57 + 28 30 14 33 + 79 176 90 91 + 29 31 14 28 + 89 192 100 101 + 105 107 49 79 + 16 18 8 107 + 88 191 99 100 + 33 35 16 29 + 76 173 90 97 + 109 111 51 80 + 137 138 64 65 + 86 87 42 98 + 26 27 12 13 + 189 190 98 103 + 202 203 81 107 + 88 89 43 100 + 20 21 9 10 + 98 100 45 66 + 179 180 92 93 + 123 124 57 58 +212 + 55 54 26 160 + 26 28 13 71 + 98 141 66 203 + 43 65 31 125 + 24 66 32 92 + 165 125 84 140 + 75 74 36 176 + 116 118 54 102 + 105 103 48 192 + 81 80 40 82 + 38 40 19 62 + 3 45 21 12 + 45 44 21 72 + 4 209 110 152 + 104 106 48 85 + 152 120 71 188 + 150 116 70 7 + 77 75 37 6 + 155 156 73 167 + 18 20 9 151 + 171 172 87 116 + 25 23 11 131 + 111 204 80 73 + 145 146 68 31 + 108 110 50 174 + 207 105 79 8 + 174 173 88 135 + 179 177 92 118 + 196 197 104 70 + 42 78 38 79 + 97 98 45 2 + 146 108 68 24 + 12 205 108 114 + 163 121 83 69 + 6 8 3 156 + 1 0 0 59 + 72 73 35 37 + 73 38 35 10 + 93 88 43 53 + 85 96 44 58 + 67 26 32 1 + 52 17 25 199 + 95 90 44 93 + 69 30 33 47 + 50 13 24 123 + 117 115 54 136 + 64 41 31 54 + 30 32 15 190 + 176 175 89 105 + 142 100 66 57 + 86 76 97 52 + 192 193 101 194 + 76 77 37 17 + 88 87 99 144 + 41 39 19 165 + 183 184 95 189 + 59 58 28 107 + 100 102 46 211 + 96 95 44 42 + 0 211 111 90 + 132 134 62 147 + 119 200 82 86 + 40 42 20 29 + 202 18 107 19 + 68 69 33 43 + 107 206 79 104 + 35 61 29 185 + 113 111 52 22 + 208 6 110 34 + 121 119 56 61 + 197 192 104 51 + 28 68 33 64 + 44 1 21 35 + 204 14 108 142 + 46 5 22 130 + 51 50 24 44 + 79 178 91 204 + 148 112 69 210 + 89 94 43 110 + 78 79 38 76 + 162 140 76 169 + 19 53 25 89 + 80 43 39 3 + 180 182 93 113 + 185 171 95 20 + 106 145 68 23 + 200 22 106 184 + 194 195 103 95 + 210 2 111 155 + 53 52 25 41 + 211 97 77 30 + 60 33 29 94 + 66 67 32 40 + 90 89 101 78 + 33 31 15 133 + 195 190 103 186 + 130 157 74 129 + 7 47 22 103 + 127 166 84 178 + 188 85 102 39 + 136 138 64 126 + 123 164 83 145 + 118 151 71 197 + 47 46 22 74 + 206 10 109 175 + 175 139 89 161 + 144 104 67 14 + 58 29 28 180 + 160 136 75 100 + 101 99 46 164 + 94 93 43 38 + 191 196 104 28 + 84 83 41 127 + 182 181 93 148 + 205 109 80 182 + 153 154 72 208 + 172 174 88 26 + 189 194 103 87 + 177 176 91 48 + 133 131 62 132 + 9 7 3 97 + 168 167 85 195 + 82 84 41 112 + 13 11 5 159 + 71 34 34 149 + 65 64 31 46 + 138 161 76 134 + 83 81 41 9 + 169 133 86 119 + 157 158 74 166 + 5 3 1 11 + 23 55 26 0 + 131 168 85 121 + 31 59 28 56 + 161 162 76 80 + 173 189 97 117 + 115 202 81 63 + 91 86 42 50 + 199 188 105 99 + 137 135 64 172 + 125 123 58 101 + 62 37 30 171 + 14 16 7 209 + 36 72 35 36 + 87 92 42 181 + 164 163 83 33 + 203 113 81 67 + 134 159 75 170 + 181 179 93 27 + 34 36 17 143 + 149 150 70 16 + 20 201 106 196 + 209 101 78 109 + 15 51 24 75 + 21 19 9 81 + 2 4 1 13 + 8 207 109 25 + 129 127 60 98 + 126 155 73 18 + 11 49 23 200 + 54 21 26 154 + 139 137 65 139 + 27 57 27 177 + 122 153 72 115 + 99 210 77 88 + 39 63 30 193 + 158 132 74 60 + 156 128 73 205 + 143 144 67 106 + 140 183 94 55 + 159 160 75 108 + 37 35 17 66 + 135 170 86 201 + 70 71 34 124 + 110 147 69 183 + 10 12 5 32 + 74 82 40 122 + 57 56 27 187 + 166 165 84 5 + 114 149 70 150 + 29 27 13 162 + 92 91 42 137 + 109 107 50 65 + 147 148 69 77 + 22 24 11 4 + 61 60 29 91 + 190 191 99 111 + 56 25 27 21 + 120 122 56 163 + 184 186 96 198 + 32 70 34 173 + 198 199 105 138 + 103 208 78 68 + 63 62 30 141 + 193 198 105 191 + 167 129 85 157 + 201 117 82 45 + 151 152 71 15 + 186 187 96 207 + 17 15 7 153 + 49 48 23 206 + 170 169 86 128 + 124 126 58 158 + 141 142 66 49 + 178 180 92 83 + 128 130 60 96 + 48 9 23 120 + 187 185 96 84 + 154 124 72 202 + 16 203 107 146 + 112 114 52 179 + 102 143 67 168 +defaultGrp +112 + -1.80042 7.84686 + 4 0 2 3 1 + -0.00000 0.64879 2.71809 + 3 57 59 81 + 7 35 59 72 88 155 11 130 + + -1.80042 7.44686 + 4 2 4 5 3 + -0.00000 0.64864 2.71920 + 2 15 81 + 6 88 155 11 130 13 74 + + -1.80042 7.04686 + 4 4 6 7 5 + -0.00000 0.64879 2.71812 + 4 10 15 51 53 + 8 13 155 74 130 34 68 97 120 + + -1.80042 6.64686 + 4 6 8 9 7 + -0.00000 0.64864 2.71914 + 2 10 34 + 6 34 68 97 120 156 206 + + -1.80042 6.24686 + 4 8 10 11 9 + -0.00000 0.64879 2.71815 + 4 34 71 74 89 + 8 34 156 120 206 104 175 123 159 + + -1.80042 5.84686 + 4 10 12 13 11 + -0.00000 0.64864 2.71903 + 2 39 89 + 6 104 175 123 159 32 44 + + -1.80042 5.44686 + 4 12 14 15 13 + -0.00000 0.64879 2.71818 + 4 20 33 39 66 + 8 32 175 44 123 73 142 153 199 + + -1.80042 5.04686 + 4 14 16 17 15 + -0.00000 0.64864 2.71896 + 2 20 67 + 6 73 142 153 199 209 41 + + -1.80042 4.64686 + 4 16 18 19 17 + -0.00000 0.64879 2.71821 + 4 7 35 67 102 + 8 142 209 41 199 19 63 81 154 + + -1.80049 4.24686 + 4 18 20 21 19 + -0.00000 0.64864 2.71884 + 2 7 113 + 6 19 63 81 154 151 160 + + -1.80057 3.84686 + 4 20 22 23 21 + -0.00000 0.64879 2.71824 + 4 31 77 79 113 + 8 19 151 154 160 86 184 21 131 + + -1.80057 3.44686 + 4 22 24 25 23 + -0.00000 0.64864 2.71875 + 2 31 55 + 6 86 184 21 131 4 187 + + -1.80057 3.04686 + 4 24 26 27 25 + -0.00000 0.64879 2.71828 + 4 55 91 93 109 + 8 4 184 21 187 1 40 162 180 + + -1.80057 2.64686 + 4 26 28 29 27 + -0.00000 0.64864 2.71868 + 2 12 109 + 6 1 40 162 180 71 107 + + -1.80057 2.24686 + 4 28 30 31 29 + -0.00000 0.64879 2.71830 + 4 12 87 97 99 + 8 1 71 107 180 43 47 94 133 + + -1.80057 1.84686 + 4 30 32 33 31 + -0.00000 0.64864 2.71859 + 2 43 87 + 6 43 47 94 133 190 91 + + -1.80057 1.44686 + 4 32 34 35 33 + -0.00000 0.64879 2.71833 + 4 25 43 58 104 + 8 47 190 91 94 124 149 66 171 + + -1.80057 1.04686 + 4 34 36 37 35 + -0.00000 0.64864 2.71850 + 2 58 63 + 6 124 149 66 171 143 141 + + -1.80057 0.64686 + 4 36 38 39 37 + -0.00000 0.64879 2.71836 + 4 1 47 50 63 + 8 143 149 141 171 10 37 54 165 + + -1.80057 0.24686 + 4 38 40 41 39 + -0.00000 0.64864 2.71841 + 2 6 50 + 6 10 37 54 165 62 46 + + -1.80057 -0.15491 + 4 40 42 43 41 + -0.00000 0.35936 2.76002 + 3 6 40 60 + 7 10 62 46 54 29 3 82 + + -6.20055 7.84686 + 4 3 45 44 1 + -0.00000 0.64879 2.71810 + 1 59 + 5 35 72 11 130 12 + + -6.20056 7.04686 + 4 7 47 46 5 + -0.00000 0.64879 2.71813 + 1 53 + 5 74 130 97 120 103 + + -6.20056 6.24686 + 4 11 49 48 9 + 0.00000 0.64879 2.71815 + 1 74 + 5 120 206 123 159 200 + + -6.20056 5.44686 + 4 15 51 50 13 + 0.00000 0.64879 2.71818 + 1 33 + 5 44 123 153 199 75 + + -6.20056 4.64686 + 4 19 53 52 17 + -0.00000 0.64879 2.71822 + 1 35 + 5 41 199 81 154 89 + + -6.20056 3.84686 + 4 23 55 54 21 + -0.00000 0.64879 2.71825 + 1 79 + 5 154 160 21 131 0 + + -6.20056 3.04686 + 4 27 57 56 25 + 0.00000 0.64879 2.71828 + 1 93 + 5 21 187 162 180 177 + + -6.20056 2.24686 + 4 31 59 58 29 + -0.00000 0.64879 2.71830 + 1 99 + 5 107 180 94 133 56 + + -6.20056 1.44686 + 4 35 61 60 33 + -0.00000 0.64879 2.71833 + 1 104 + 5 91 94 66 171 185 + + -6.20056 0.64686 + 4 39 63 62 37 + 0.00000 0.64879 2.71837 + 1 1 + 5 141 171 54 165 193 + + -6.20056 -0.15491 + 4 43 65 64 41 + 0.00000 0.35936 2.76002 + 1 40 + 5 46 54 3 82 125 + + -0.70056 3.04686 + 4 24 66 67 26 + 0.00000 0.64879 2.71828 + 1 91 + 5 4 184 1 40 92 + + -0.70056 2.24686 + 4 28 68 69 30 + 0.00000 0.64879 2.71830 + 1 97 + 5 1 71 43 47 64 + + -0.70056 1.44686 + 4 32 70 71 34 + 0.00000 0.64879 2.71833 + 1 25 + 5 47 190 124 149 173 + + -0.70056 0.64686 + 4 36 72 73 38 + 0.00000 0.64879 2.71836 + 1 47 + 5 143 149 10 37 36 + + -1.80057 -0.90087 + 4 42 75 74 80 + 0.00000 0.00000 2.59700 + 3 52 78 84 + 7 29 62 6 176 17 9 82 + + -0.30049 -0.78690 + 4 42 76 77 75 + 0.00000 -0.00000 2.59700 + 2 13 84 + 6 29 62 6 17 50 52 + + -0.44940 0.01310 + 4 42 78 79 76 + 0.00000 0.00000 2.59700 + 2 13 83 + 6 29 62 50 52 79 76 + + -2.00057 -0.51661 + 3 42 80 43 + -0.00000 0.00000 2.59700 + 2 60 78 + 5 29 62 3 82 9 + + -2.80092 -0.94809 + 4 74 82 81 80 + 0.64818 -0.00000 4.15300 + 2 52 56 + 6 6 176 9 82 127 122 + + -6.60091 -0.94809 + 4 82 84 83 81 + 0.00000 -0.00000 2.07800 + 1 56 + 5 9 127 122 176 112 + + -4.70042 -1.73919 + 4 87 92 91 86 + -0.00000 0.64875 2.71810 + 1 108 + 5 50 137 53 144 181 + + -4.70042 -2.52630 + 4 89 94 93 88 + 0.00000 0.64875 2.71810 + 1 112 + 5 38 53 78 93 110 + + -4.70042 -3.33629 + 4 85 96 95 90 + 0.00000 0.37588 1.89433 + 1 14 + 5 39 99 42 93 58 + + 4.20000 7.84686 + 4 97 98 100 99 + 0.00000 0.64879 2.71809 + 3 24 86 114 + 7 30 90 2 109 164 49 57 + + 4.20001 7.44686 + 4 99 100 102 101 + 0.00000 0.64864 2.71920 + 2 4 24 + 6 109 164 49 57 152 211 + + 4.20001 7.04686 + 4 101 102 104 103 + 0.00000 0.64879 2.71812 + 4 4 42 68 70 + 8 109 152 57 211 8 192 14 106 + + 4.20001 6.64686 + 4 103 104 106 105 + 0.00000 0.64864 2.71914 + 2 18 42 + 6 8 192 14 106 25 85 + + 4.20001 6.24686 + 4 105 106 108 107 + 0.00000 0.64879 2.71815 + 4 5 18 22 101 + 8 8 25 14 85 65 182 24 31 + + 4.20001 5.84686 + 4 107 108 110 109 + 0.00000 0.64864 2.71902 + 2 22 23 + 6 65 182 24 31 114 174 + + 4.20001 5.44686 + 4 109 110 112 111 + 0.00000 0.64879 2.71818 + 4 23 28 92 106 + 8 114 182 24 174 22 67 77 210 + + 4.20001 5.04686 + 4 111 112 114 113 + 0.00000 0.64864 2.71896 + 2 90 92 + 6 22 67 77 210 146 179 + + 4.20001 4.64686 + 4 113 114 116 115 + 0.00000 0.64879 2.71821 + 4 11 30 65 90 + 8 67 146 179 210 45 136 7 16 + + 4.20001 4.24686 + 4 115 116 118 117 + 0.00000 0.64864 2.71884 + 2 11 26 + 6 45 136 7 16 196 102 + + 4.20001 3.84686 + 4 117 118 120 119 + 0.00000 0.64879 2.71824 + 4 26 45 75 82 + 8 45 196 7 102 61 69 15 188 + + 4.20001 3.44686 + 4 119 120 122 121 + 0.00000 0.64864 2.71875 + 2 82 96 + 6 61 69 15 188 33 163 + + 4.20001 3.04686 + 4 121 122 124 123 + 0.00000 0.64879 2.71828 + 4 17 80 96 116 + 8 33 69 163 188 101 140 202 208 + + 4.20001 2.64686 + 4 123 124 126 125 + 0.00000 0.64864 2.71868 + 2 2 116 + 6 101 140 202 208 5 158 + + 4.20001 2.24686 + 4 125 126 128 127 + 0.00000 0.64879 2.71830 + 4 2 8 41 85 + 8 5 140 158 202 98 157 167 205 + + 4.20001 1.84686 + 4 127 128 130 129 + 0.00000 0.64864 2.71859 + 2 8 95 + 6 98 157 167 205 195 96 + + 4.20001 1.44686 + 4 129 130 132 131 + 0.00000 0.64879 2.71833 + 4 29 32 54 95 + 8 157 195 96 205 119 132 60 166 + + 4.20001 1.04686 + 4 131 132 134 133 + 0.00000 0.64864 2.71850 + 2 29 73 + 6 119 132 60 166 128 147 + + 4.20001 0.64686 + 4 133 134 136 135 + 0.00000 0.64879 2.71836 + 4 38 62 73 88 + 8 119 128 60 147 139 172 100 108 + + 4.20001 0.24686 + 4 135 136 138 137 + 0.00000 0.64864 2.71841 + 2 88 107 + 6 139 172 100 108 161 126 + + 4.20001 -0.15491 + 4 137 138 140 139 + 0.00000 0.35936 2.76002 + 3 36 46 107 + 7 139 161 100 126 105 80 169 + + 8.60000 7.84686 + 4 100 98 141 142 + 0.00000 0.64879 2.71810 + 1 114 + 5 2 30 49 57 203 + + 8.60001 7.04686 + 4 104 102 143 144 + -0.00000 0.64879 2.71813 + 1 68 + 5 57 211 14 106 168 + + 8.60001 6.24686 + 4 108 106 145 146 + 0.00000 0.64879 2.71815 + 1 5 + 5 14 85 24 31 23 + + 8.60001 5.44686 + 4 112 110 147 148 + -0.00000 0.64879 2.71818 + 1 28 + 5 24 174 77 210 183 + + 8.60001 4.64686 + 4 116 114 149 150 + 0.00000 0.64879 2.71822 + 1 30 + 5 179 210 7 16 150 + + 8.60001 3.84686 + 4 120 118 151 152 + 0.00000 0.64879 2.71825 + 1 45 + 5 7 102 15 188 197 + + 8.60001 3.04686 + 4 124 122 153 154 + 0.00000 0.64879 2.71828 + 1 17 + 5 163 188 202 208 115 + + 8.60001 2.24686 + 4 128 126 155 156 + 0.00000 0.64879 2.71830 + 1 41 + 5 158 202 167 205 18 + + 8.60001 1.44686 + 4 132 130 157 158 + 0.00000 0.64879 2.71833 + 1 54 + 5 96 205 60 166 129 + + 8.60001 0.64686 + 4 136 134 159 160 + -0.00000 0.64879 2.71837 + 1 38 + 5 60 147 100 108 170 + + 8.60001 -0.15491 + 4 140 138 161 162 + 0.00000 0.35936 2.76002 + 1 36 + 5 100 126 80 169 134 + + 2.39993 7.84686 + 4 97 99 210 211 + 0.00000 0.64879 2.71809 + 2 61 86 + 6 30 90 109 164 88 59 + + 2.39990 7.04686 + 4 101 103 208 209 + 0.00000 0.64879 2.71812 + 2 48 70 + 6 109 152 8 192 68 13 + + 2.39987 6.24686 + 4 105 107 206 207 + -0.00000 0.64879 2.71814 + 2 44 101 + 6 8 25 65 182 104 156 + + 2.39987 5.44686 + 4 109 111 204 205 + -0.00000 0.64879 2.71817 + 2 76 106 + 6 114 182 22 67 73 32 + + 2.39987 4.64686 + 4 113 115 202 203 + -0.00000 0.64879 2.71821 + 2 65 111 + 6 67 146 45 136 63 209 + + 2.39987 3.84686 + 4 117 119 200 201 + 0.00000 0.64879 2.71824 + 2 3 75 + 6 45 196 61 69 86 151 + + 3.10001 3.04686 + 4 121 123 164 163 + 0.00000 0.64879 2.71828 + 1 80 + 5 33 69 101 140 145 + + 3.10001 2.24686 + 4 125 127 166 165 + 0.00000 0.64879 2.71830 + 1 85 + 5 5 140 98 157 178 + + 3.10001 1.44686 + 4 129 131 168 167 + 0.00000 0.64879 2.71833 + 1 32 + 5 157 195 119 132 121 + + 3.10001 0.64686 + 4 133 135 170 169 + 0.00000 0.64879 2.71836 + 1 62 + 5 119 128 139 172 201 + + 4.20001 -0.90087 + 4 139 183 171 172 + 0.00000 0.00000 2.59700 + 3 37 64 69 + 7 105 161 20 84 116 55 169 + + 2.70001 -0.78690 + 4 139 172 174 173 + 0.00000 0.00000 2.59700 + 2 21 37 + 6 105 161 20 116 26 135 + + 2.84891 0.01310 + 4 139 173 176 175 + 0.00000 0.00000 2.59700 + 2 21 72 + 6 105 161 26 135 48 118 + + 1.19979 0.07984 + 4 176 173 76 79 + 0.00000 -0.00000 2.59700 + 4 72 83 98 105 + 8 50 52 76 79 26 135 48 118 + + 1.19972 4.24635 + 4 176 79 178 177 + -0.00000 0.00000 2.59700 + 2 16 98 + 6 76 79 48 118 27 204 + + 1.19972 9.28715 + 4 177 178 180 179 + 0.00000 0.00000 2.59700 + 2 16 115 + 6 27 118 76 204 148 83 + + 1.19972 15.47307 + 4 179 180 182 181 + -0.00000 -0.00000 2.59700 + 1 115 + 5 27 148 83 204 113 + + 4.40001 -0.51661 + 3 139 140 183 + 0.00000 -0.00000 2.59700 + 2 46 69 + 5 105 161 80 169 55 + + 5.20036 -0.94809 + 4 171 183 184 185 + -0.64818 0.00000 5.70827 + 2 9 64 + 6 20 84 55 169 189 207 + + 9.00036 -0.94809 + 4 185 184 186 187 + -0.00000 0.00000 2.07800 + 1 9 + 5 55 189 84 207 198 + + 1.19986 -0.82096 + 4 76 173 189 86 + 0.00000 0.64875 2.71810 + 2 49 105 + 6 50 52 137 26 135 117 + + 1.19986 -1.73919 + 4 86 189 190 87 + 0.00000 0.64875 2.71810 + 4 0 49 108 110 + 8 50 137 53 144 117 135 95 186 + + 1.19986 -2.12571 + 4 87 190 191 88 + 0.00000 0.64875 2.71810 + 2 0 103 + 6 53 144 38 95 186 111 + + 1.19986 -2.52630 + 4 88 191 192 89 + 0.00000 0.64875 2.71810 + 4 19 100 103 112 + 8 38 53 78 93 111 186 51 70 + + 1.19986 -2.92161 + 4 89 192 193 90 + 0.00000 0.64875 2.71811 + 2 94 100 + 6 78 93 42 51 70 194 + + 1.19986 -3.33629 + 4 90 193 188 85 + -0.00000 0.37588 1.89433 + 3 14 27 94 + 7 39 99 42 93 138 51 194 + + 7.10000 -1.73919 + 4 190 189 194 195 + -0.00000 0.64875 2.71810 + 1 110 + 5 117 135 95 186 87 + + 7.10000 -2.52630 + 4 192 191 196 197 + -0.00000 0.64875 2.71810 + 1 19 + 5 111 186 51 70 28 + + 7.10000 -3.33629 + 4 188 193 198 199 + -0.00000 0.37588 1.89433 + 1 27 + 5 99 138 51 194 191 + + -0.00042 3.84686 + 4 201 200 22 20 + -0.00000 0.64879 2.71824 + 2 3 77 + 6 19 151 86 184 61 196 + + -0.00028 4.64686 + 4 203 202 18 16 + 0.00000 0.64879 2.71821 + 2 102 111 + 6 142 209 19 63 136 146 + + -0.00028 5.44686 + 4 205 204 14 12 + 0.00000 0.64879 2.71817 + 2 66 76 + 6 32 175 73 142 22 114 + + -0.00028 6.24686 + 4 207 206 10 8 + 0.00000 0.64879 2.71814 + 2 44 71 + 6 34 156 104 175 65 25 + + -0.00024 7.04686 + 4 209 208 6 4 + -0.00000 0.64879 2.71812 + 2 48 51 + 6 13 155 34 68 192 152 + + -0.00021 7.84686 + 4 211 210 2 0 + 0.00000 0.64879 2.71809 + 2 57 61 + 6 35 59 88 155 164 90 diff --git a/examples/core/soccer/soccerB.xml b/examples/core/soccer/soccerB.xml new file mode 100644 index 00000000..9c459e86 --- /dev/null +++ b/examples/core/soccer/soccerB.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + // Into tunnel + + + + + + + + \ No newline at end of file diff --git a/examples/core/soccer/soccerS.xml b/examples/core/soccer/soccerS.xml new file mode 100644 index 00000000..696dd80a --- /dev/null +++ b/examples/core/soccer/soccerS.xml @@ -0,0 +1,420 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/soccer/soccerV.xml b/examples/core/soccer/soccerV.xml new file mode 100644 index 00000000..a950f99a --- /dev/null +++ b/examples/core/soccer/soccerV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/core/stadium.xml b/examples/core/stadium.xml new file mode 100644 index 00000000..dc941cff --- /dev/null +++ b/examples/core/stadium.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/stadium/stadium.nav b/examples/core/stadium/stadium.nav new file mode 100644 index 00000000..910dd6bc --- /dev/null +++ b/examples/core/stadium/stadium.nav @@ -0,0 +1,342 @@ +88 + -1.00 0.00 + 1.00 0.00 + 1.00 7.50 + -1.00 7.50 + -10.00 0.00 + -10.00 -10.00 + 10.00 -10.00 + 10.00 0.00 + -10.00 0.35 + -1.00 0.35 + -1.00 0.85 + -10.00 0.85 + 10.00 0.85 + 1.00 0.85 + 1.00 0.35 + 10.00 0.35 + -10.00 1.05 + -1.00 1.05 + -1.00 1.55 + -10.00 1.55 + 10.00 1.55 + 1.00 1.55 + 1.00 1.05 + 10.00 1.05 + -10.00 1.75 + -1.00 1.75 + -1.00 2.25 + -10.00 2.25 + 10.00 2.25 + 1.00 2.25 + 1.00 1.75 + 10.00 1.75 + -10.00 2.45 + -1.00 2.45 + -1.00 2.95 + -10.00 2.95 + 10.00 2.95 + 1.00 2.95 + 1.00 2.45 + 10.00 2.45 + -10.00 3.15 + -1.00 3.15 + -1.00 3.65 + -10.00 3.65 + 10.00 3.65 + 1.00 3.65 + 1.00 3.15 + 10.00 3.15 + -10.00 3.85 + -1.00 3.85 + -1.00 4.35 + -10.00 4.35 + 10.00 4.35 + 1.00 4.35 + 1.00 3.85 + 10.00 3.85 + -10.00 4.55 + -1.00 4.55 + -1.00 5.05 + -10.00 5.05 + 10.00 5.05 + 1.00 5.05 + 1.00 4.55 + 10.00 4.55 + -10.00 5.25 + -1.00 5.25 + -1.00 5.75 + -10.00 5.75 + 10.00 5.75 + 1.00 5.75 + 1.00 5.25 + 10.00 5.25 + -10.00 5.95 + -1.00 5.95 + -1.00 6.45 + -10.00 6.45 + 10.00 6.45 + 1.00 6.45 + 1.00 5.95 + 10.00 5.95 + -10.00 6.65 + -1.00 6.65 + -1.00 7.15 + -10.00 7.15 + 10.00 7.15 + 1.00 7.15 + 1.00 6.65 + 10.00 6.65 + +21 + 0 1 0 1 + 9 10 0 2 + 13 14 0 3 + 17 18 0 4 + 21 22 0 5 + 25 26 0 6 + 29 30 0 7 + 33 34 0 8 + 37 38 0 9 + 41 42 0 10 + 45 46 0 11 + 49 50 0 12 + 53 54 0 13 + 57 58 0 14 + 61 62 0 15 + 65 66 0 16 + 69 70 0 17 + 73 74 0 18 + 77 78 0 19 + 81 82 0 20 + 85 86 0 21 + +88 + 1 7 1 1 + 7 6 1 2 + 6 5 1 3 + 5 4 1 4 + 4 0 1 5 + 0 9 0 6 + 9 8 2 7 + 8 11 2 8 + 11 10 2 13 + 14 1 0 0 + 15 14 3 9 + 12 15 3 10 + 13 12 3 11 + 10 17 0 14 + 17 16 4 15 + 16 19 4 16 + 19 18 4 21 + 22 13 0 12 + 23 22 5 17 + 20 23 5 18 + 21 20 5 19 + 18 25 0 22 + 25 24 6 23 + 24 27 6 24 + 27 26 6 29 + 30 21 0 20 + 31 30 7 25 + 28 31 7 26 + 29 28 7 27 + 26 33 0 30 + 33 32 8 31 + 32 35 8 32 + 35 34 8 37 + 38 29 0 28 + 39 38 9 33 + 36 39 9 34 + 37 36 9 35 + 34 41 0 38 + 41 40 10 39 + 40 43 10 40 + 43 42 10 45 + 46 37 0 36 + 47 46 11 41 + 44 47 11 42 + 45 44 11 43 + 42 49 0 46 + 49 48 12 47 + 48 51 12 48 + 51 50 12 53 + 54 45 0 44 + 55 54 13 49 + 52 55 13 50 + 53 52 13 51 + 50 57 0 54 + 57 56 14 55 + 56 59 14 56 + 59 58 14 61 + 62 53 0 52 + 63 62 15 57 + 60 63 15 58 + 61 60 15 59 + 58 65 0 62 + 65 64 16 63 + 64 67 16 64 + 67 66 16 69 + 70 61 0 60 + 71 70 17 65 + 68 71 17 66 + 69 68 17 67 + 66 73 0 70 + 73 72 18 71 + 72 75 18 72 + 75 74 18 77 + 78 69 0 68 + 79 78 19 73 + 76 79 19 74 + 77 76 19 75 + 74 81 0 78 + 81 80 20 79 + 80 83 20 80 + 83 82 20 85 + 86 77 0 76 + 87 86 21 81 + 84 87 21 82 + 85 84 21 83 + 82 3 0 86 + 3 2 0 87 + 2 85 0 84 + +stairGrp +1 + 0.0000 3.7500 + 4 0 1 2 3 + 0.0000 0.6745 0.0000 + 21 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 68 0 1 2 3 4 5 6 8 9 10 12 13 14 16 17 18 20 21 22 24 25 26 28 29 30 32 33 34 36 37 38 40 41 42 44 45 46 48 49 50 52 53 54 56 57 58 60 61 62 64 65 66 68 69 70 72 73 74 76 77 78 80 81 82 84 85 86 87 + + +floorGrp +1 + 0.0000 -5.0000 + 4 4 5 6 7 + 0.0000 0.0000 0.0000 + 1 0 + 7 0 1 2 3 4 5 9 + + +rowsGrp +20 + -5.5000 0.6000 + 4 8 9 10 11 + 0.0000 0.0000 0.4047 + 1 1 + 5 5 6 7 8 13 + + 5.5000 0.6000 + 4 12 13 14 15 + 0.0000 0.0000 0.4047 + 1 2 + 5 9 10 11 12 17 + + -5.5000 1.3000 + 4 16 17 18 19 + 0.0000 0.0000 0.8769 + 1 3 + 5 13 14 15 16 21 + + 5.5000 1.3000 + 4 20 21 22 23 + 0.0000 0.0000 0.8769 + 1 4 + 5 17 18 19 20 25 + + -5.5000 2.0000 + 4 24 25 26 27 + 0.0000 0.0000 1.3490 + 1 5 + 5 21 22 23 24 29 + + 5.5000 2.0000 + 4 28 29 30 31 + 0.0000 0.0000 1.3490 + 1 6 + 5 25 26 27 28 33 + + -5.5000 2.7000 + 4 32 33 34 35 + 0.0000 0.0000 1.8212 + 1 7 + 5 29 30 31 32 37 + + 5.5000 2.7000 + 4 36 37 38 39 + 0.0000 0.0000 1.8212 + 1 8 + 5 33 34 35 36 41 + + -5.5000 3.4000 + 4 40 41 42 43 + 0.0000 0.0000 2.2933 + 1 9 + 5 37 38 39 40 45 + + 5.5000 3.4000 + 4 44 45 46 47 + 0.0000 0.0000 2.2933 + 1 10 + 5 41 42 43 44 49 + + -5.5000 4.1000 + 4 48 49 50 51 + 0.0000 0.0000 2.7655 + 1 11 + 5 45 46 47 48 53 + + 5.5000 4.1000 + 4 52 53 54 55 + 0.0000 0.0000 2.7655 + 1 12 + 5 49 50 51 52 57 + + -5.5000 4.8000 + 4 56 57 58 59 + 0.0000 0.0000 3.2376 + 1 13 + 5 53 54 55 56 61 + + 5.5000 4.8000 + 4 60 61 62 63 + 0.0000 0.0000 3.2376 + 1 14 + 5 57 58 59 60 65 + + -5.5000 5.5000 + 4 64 65 66 67 + 0.0000 0.0000 3.7098 + 1 15 + 5 61 62 63 64 69 + + 5.5000 5.5000 + 4 68 69 70 71 + 0.0000 0.0000 3.7098 + 1 16 + 5 65 66 67 68 73 + + -5.5000 6.2000 + 4 72 73 74 75 + 0.0000 0.0000 4.1820 + 1 17 + 5 69 70 71 72 77 + + 5.5000 6.2000 + 4 76 77 78 79 + 0.0000 0.0000 4.1820 + 1 18 + 5 73 74 75 76 81 + + -5.5000 6.9000 + 4 80 81 82 83 + 0.0000 0.0000 4.6541 + 1 19 + 5 77 78 79 80 85 + + 5.5000 6.9000 + 4 84 85 86 87 + 0.0000 0.0000 4.6541 + 1 20 + 5 81 82 83 84 87 diff --git a/examples/core/stadium/stadiumB.xml b/examples/core/stadium/stadiumB.xml new file mode 100644 index 00000000..6012805f --- /dev/null +++ b/examples/core/stadium/stadiumB.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/stadium/stadiumS.xml b/examples/core/stadium/stadiumS.xml new file mode 100644 index 00000000..a1f347c6 --- /dev/null +++ b/examples/core/stadium/stadiumS.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/stadium/stadiumV.xml b/examples/core/stadium/stadiumV.xml new file mode 100644 index 00000000..a950f99a --- /dev/null +++ b/examples/core/stadium/stadiumV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/core/steerbench/4wayconfusion.xml b/examples/core/steerbench/4wayconfusion.xml new file mode 100644 index 00000000..048b42f7 --- /dev/null +++ b/examples/core/steerbench/4wayconfusion.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/4wayconfusion/4wayconfusionB.xml b/examples/core/steerbench/4wayconfusion/4wayconfusionB.xml new file mode 100644 index 00000000..3d37d493 --- /dev/null +++ b/examples/core/steerbench/4wayconfusion/4wayconfusionB.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/4wayconfusion/4wayconfusionS.xml b/examples/core/steerbench/4wayconfusion/4wayconfusionS.xml new file mode 100644 index 00000000..32576c75 --- /dev/null +++ b/examples/core/steerbench/4wayconfusion/4wayconfusionS.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/4wayconfusion/4wayconfusionV.xml b/examples/core/steerbench/4wayconfusion/4wayconfusionV.xml new file mode 100644 index 00000000..43769320 --- /dev/null +++ b/examples/core/steerbench/4wayconfusion/4wayconfusionV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/curves.xml b/examples/core/steerbench/curves.xml new file mode 100644 index 00000000..3d922047 --- /dev/null +++ b/examples/core/steerbench/curves.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/curves/curvesB.xml b/examples/core/steerbench/curves/curvesB.xml new file mode 100644 index 00000000..8153f479 --- /dev/null +++ b/examples/core/steerbench/curves/curvesB.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/curves/curvesS.xml b/examples/core/steerbench/curves/curvesS.xml new file mode 100644 index 00000000..7efed789 --- /dev/null +++ b/examples/core/steerbench/curves/curvesS.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/curves/curvesV.xml b/examples/core/steerbench/curves/curvesV.xml new file mode 100644 index 00000000..82ac53ac --- /dev/null +++ b/examples/core/steerbench/curves/curvesV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/curves/graph.txt b/examples/core/steerbench/curves/graph.txt new file mode 100644 index 00000000..4e47f6d7 --- /dev/null +++ b/examples/core/steerbench/curves/graph.txt @@ -0,0 +1,22 @@ +10 +2 5.505616 -1.983127 +2 7.882114 1.102151 +2 4.880222 4.979596 +2 0.627540 5.021289 +2 -5.292859 4.979596 +2 -7.169042 8.982120 +2 -5.376245 13.651731 +1 -0.122933 13.693424 +2 2.128487 -3.692538 +1 -0.706634 -3.734231 +9 +1 0 +2 1 +3 2 +4 3 +5 4 +6 5 +7 6 +8 0 +9 8 + diff --git a/examples/core/steerbench/doorwayTwoway.xml b/examples/core/steerbench/doorwayTwoway.xml new file mode 100644 index 00000000..6156e725 --- /dev/null +++ b/examples/core/steerbench/doorwayTwoway.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/doorwayTwoway/doorwayTwowayB.xml b/examples/core/steerbench/doorwayTwoway/doorwayTwowayB.xml new file mode 100644 index 00000000..d49591a8 --- /dev/null +++ b/examples/core/steerbench/doorwayTwoway/doorwayTwowayB.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/doorwayTwoway/doorwayTwowayS.xml b/examples/core/steerbench/doorwayTwoway/doorwayTwowayS.xml new file mode 100644 index 00000000..c7263019 --- /dev/null +++ b/examples/core/steerbench/doorwayTwoway/doorwayTwowayS.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/doorwayTwoway/doorwayTwowayV.xml b/examples/core/steerbench/doorwayTwoway/doorwayTwowayV.xml new file mode 100644 index 00000000..89600e87 --- /dev/null +++ b/examples/core/steerbench/doorwayTwoway/doorwayTwowayV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/doorwayTwoway/graph.txt b/examples/core/steerbench/doorwayTwoway/graph.txt new file mode 100644 index 00000000..68accb5f --- /dev/null +++ b/examples/core/steerbench/doorwayTwoway/graph.txt @@ -0,0 +1,10 @@ +4 +1 -1.936493 -4.999044 +2 -0.212708 -0.511308 +2 0.173365 0.461631 +1 1.934493 4.899029 +3 +1 0 +2 1 +3 2 + diff --git a/examples/core/steerbench/doubleSqueeze.xml b/examples/core/steerbench/doubleSqueeze.xml new file mode 100644 index 00000000..b3ec61eb --- /dev/null +++ b/examples/core/steerbench/doubleSqueeze.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/doubleSqueeze/doubleSqueezeB.xml b/examples/core/steerbench/doubleSqueeze/doubleSqueezeB.xml new file mode 100644 index 00000000..86b0f478 --- /dev/null +++ b/examples/core/steerbench/doubleSqueeze/doubleSqueezeB.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/doubleSqueeze/doubleSqueezeS.xml b/examples/core/steerbench/doubleSqueeze/doubleSqueezeS.xml new file mode 100644 index 00000000..3f653653 --- /dev/null +++ b/examples/core/steerbench/doubleSqueeze/doubleSqueezeS.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/doubleSqueeze/doubleSqueezeV.xml b/examples/core/steerbench/doubleSqueeze/doubleSqueezeV.xml new file mode 100644 index 00000000..9bd80bdb --- /dev/null +++ b/examples/core/steerbench/doubleSqueeze/doubleSqueezeV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/frogger.xml b/examples/core/steerbench/frogger.xml new file mode 100644 index 00000000..d57e1f84 --- /dev/null +++ b/examples/core/steerbench/frogger.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/frogger/froggerB.xml b/examples/core/steerbench/frogger/froggerB.xml new file mode 100644 index 00000000..757e4311 --- /dev/null +++ b/examples/core/steerbench/frogger/froggerB.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/frogger/froggerS.xml b/examples/core/steerbench/frogger/froggerS.xml new file mode 100644 index 00000000..e738c24a --- /dev/null +++ b/examples/core/steerbench/frogger/froggerS.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/frogger/froggerV.xml b/examples/core/steerbench/frogger/froggerV.xml new file mode 100644 index 00000000..fd96ed22 --- /dev/null +++ b/examples/core/steerbench/frogger/froggerV.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/core/steerbench/oncomingObstacle.xml b/examples/core/steerbench/oncomingObstacle.xml new file mode 100644 index 00000000..1b304906 --- /dev/null +++ b/examples/core/steerbench/oncomingObstacle.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/oncomingObstacle/graph.txt b/examples/core/steerbench/oncomingObstacle/graph.txt new file mode 100644 index 00000000..0174f99e --- /dev/null +++ b/examples/core/steerbench/oncomingObstacle/graph.txt @@ -0,0 +1,11 @@ +4 +2 -1.610520 4.646527 +2 -2.651006 0.001496 +2 -0.086949 -0.072824 +2 -1.424718 -3.268606 +4 +2 0 +0 1 +3 2 +3 1 + diff --git a/examples/core/steerbench/oncomingObstacle/oncomingObstacleB.xml b/examples/core/steerbench/oncomingObstacle/oncomingObstacleB.xml new file mode 100644 index 00000000..d9dbc4b3 --- /dev/null +++ b/examples/core/steerbench/oncomingObstacle/oncomingObstacleB.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/oncomingObstacle/oncomingObstacleS.xml b/examples/core/steerbench/oncomingObstacle/oncomingObstacleS.xml new file mode 100644 index 00000000..ca879f68 --- /dev/null +++ b/examples/core/steerbench/oncomingObstacle/oncomingObstacleS.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/oncomingObstacle/oncomingObstacleV.xml b/examples/core/steerbench/oncomingObstacle/oncomingObstacleV.xml new file mode 100644 index 00000000..3864a272 --- /dev/null +++ b/examples/core/steerbench/oncomingObstacle/oncomingObstacleV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/simple.xml b/examples/core/steerbench/simple.xml new file mode 100644 index 00000000..6257aa0a --- /dev/null +++ b/examples/core/steerbench/simple.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/simple/simpleB.xml b/examples/core/steerbench/simple/simpleB.xml new file mode 100644 index 00000000..200568a0 --- /dev/null +++ b/examples/core/steerbench/simple/simpleB.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/simple/simpleS.xml b/examples/core/steerbench/simple/simpleS.xml new file mode 100644 index 00000000..cff5a0e4 --- /dev/null +++ b/examples/core/steerbench/simple/simpleS.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/simple/simpleV.xml b/examples/core/steerbench/simple/simpleV.xml new file mode 100644 index 00000000..769bf8a7 --- /dev/null +++ b/examples/core/steerbench/simple/simpleV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/surprise.xml b/examples/core/steerbench/surprise.xml new file mode 100644 index 00000000..8c55794e --- /dev/null +++ b/examples/core/steerbench/surprise.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/surprise/surpriseB.xml b/examples/core/steerbench/surprise/surpriseB.xml new file mode 100644 index 00000000..987fb247 --- /dev/null +++ b/examples/core/steerbench/surprise/surpriseB.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/surprise/surpriseS.xml b/examples/core/steerbench/surprise/surpriseS.xml new file mode 100644 index 00000000..cbd2d08f --- /dev/null +++ b/examples/core/steerbench/surprise/surpriseS.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/surprise/surpriseV.xml b/examples/core/steerbench/surprise/surpriseV.xml new file mode 100644 index 00000000..43769320 --- /dev/null +++ b/examples/core/steerbench/surprise/surpriseV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/steerbench/wallSqueeze.xml b/examples/core/steerbench/wallSqueeze.xml new file mode 100644 index 00000000..d74b56b1 --- /dev/null +++ b/examples/core/steerbench/wallSqueeze.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/steerbench/wallSqueeze/wallSqueezeB.xml b/examples/core/steerbench/wallSqueeze/wallSqueezeB.xml new file mode 100644 index 00000000..ed1a547f --- /dev/null +++ b/examples/core/steerbench/wallSqueeze/wallSqueezeB.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/wallSqueeze/wallSqueezeS.xml b/examples/core/steerbench/wallSqueeze/wallSqueezeS.xml new file mode 100644 index 00000000..5bb39131 --- /dev/null +++ b/examples/core/steerbench/wallSqueeze/wallSqueezeS.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/steerbench/wallSqueeze/wallSqueezeV.xml b/examples/core/steerbench/wallSqueeze/wallSqueezeV.xml new file mode 100644 index 00000000..43769320 --- /dev/null +++ b/examples/core/steerbench/wallSqueeze/wallSqueezeV.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/core/swap.xml b/examples/core/swap.xml new file mode 100644 index 00000000..54afba6c --- /dev/null +++ b/examples/core/swap.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/swap/swapB.xml b/examples/core/swap/swapB.xml new file mode 100644 index 00000000..8c873ecd --- /dev/null +++ b/examples/core/swap/swapB.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/swap/swapS.xml b/examples/core/swap/swapS.xml new file mode 100644 index 00000000..fcc293c9 --- /dev/null +++ b/examples/core/swap/swapS.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/swap/swapV.xml b/examples/core/swap/swapV.xml new file mode 100644 index 00000000..57633737 --- /dev/null +++ b/examples/core/swap/swapV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/core/tradeshow.xml b/examples/core/tradeshow.xml new file mode 100644 index 00000000..828deb6b --- /dev/null +++ b/examples/core/tradeshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/core/tradeshow/tradeshow.nav b/examples/core/tradeshow/tradeshow.nav new file mode 100644 index 00000000..901bf2e7 --- /dev/null +++ b/examples/core/tradeshow/tradeshow.nav @@ -0,0 +1,3391 @@ +470 + 26.80000 -33.00000 + 26.80000 34.00000 + -11.29810 -31.03328 + -11.29810 -32.74832 + -5.04473 -32.74832 + -5.04473 -31.03328 + -14.09070 -19.08301 + -14.09070 -24.27472 + -10.19596 -24.27472 + -10.19596 -19.08301 + -8.00200 -18.54208 + -8.00200 -22.95766 + -5.20707 -22.95766 + -5.20707 -18.54208 + -3.29487 -18.75085 + -3.29487 -22.01677 + 4.71598 -22.01677 + 4.71598 -18.75085 + -2.11564 -23.85509 + -2.11564 -27.01770 + 4.35272 -27.01770 + 4.35272 -23.85509 + 6.87824 -16.14320 + 6.87824 -21.96540 + 10.21278 -21.96540 + 10.21278 -16.14320 + 5.89125 -24.63143 + 5.89125 -29.39567 + 11.35795 -29.39567 + 11.35795 -24.63143 + -20.27086 -25.69694 + -20.27086 -29.05100 + -12.35968 -29.05100 + -12.35968 -25.69694 + -19.28401 -22.84020 + -19.28401 -24.33571 + -16.41213 -24.33571 + -16.41213 -22.84020 + -22.54220 -18.65516 + -22.54220 -24.30763 + -21.04702 -24.30763 + -21.04702 -18.65516 + -7.58607 -24.90485 + -9.39508 -26.51231 + -9.39508 -27.38756 + -8.18070 -29.56243 + -5.97630 -29.56243 + -3.18788 -26.73476 + -3.18788 -26.29602 + -4.65391 -24.90485 + 5.78904 -30.82466 + 21.87566 -30.82466 + 16.38080 -23.04786 + 14.65294 -24.33276 + 14.65294 -26.41843 + 16.09830 -27.81570 + 18.15191 -27.81570 + 19.37970 -25.95433 + 19.37970 -25.24079 + 18.25280 -23.04786 + 20.49665 -26.34502 + 18.97621 -28.57405 + 20.10888 -28.84435 + 21.25342 -27.22772 + 23.47201 0.40180 + 23.47201 -21.23815 + 26.21861 -21.23815 + 26.21861 0.40180 + 20.43997 -13.78935 + 14.17870 -13.78935 + 14.17870 -21.35425 + 17.30964 -21.35425 + 20.43997 -19.18697 + -22.81256 -28.48431 + -16.64887 -32.74081 + -16.64887 -31.02408 + -20.37754 -31.02408 + -22.43835 -29.34004 + -25.98111 -24.67207 + -22.98210 -26.02854 + -24.72187 -24.67207 + -25.92940 -12.15559 + -25.92940 -24.05662 + -24.15437 -24.05662 + -24.15437 -12.15559 + -21.38143 -10.77469 + -21.38143 -17.27451 + -15.49832 -17.27451 + -15.49832 -14.55502 + -18.78671 -10.77469 + 4.93287 -32.72167 + 4.93287 -31.64902 + 3.57990 -29.88462 + -3.80348 -29.56663 + -3.80348 -29.96442 + -3.40570 -29.96442 + -3.40570 -29.56663 + -1.90204 -27.80241 + -1.90204 -32.71184 + -0.47105 -27.80241 + 1.07673 -29.26214 + -13.90702 -10.80928 + -13.90702 -17.44986 + -10.13501 -17.44986 + -10.13501 -10.80928 + -8.29665 -11.30746 + -8.29665 -17.10590 + -5.28912 -17.10590 + -5.28912 -12.31750 + -7.03280 -11.30746 + 3.53445 -10.80188 + -1.28297 -10.80188 + -2.74314 -12.73041 + -2.74314 -17.19061 + 0.49354 -17.19061 + 3.53445 -15.63287 + -2.22316 -6.08455 + -2.22316 -9.29237 + 3.73152 -9.29237 + 3.73152 -6.08455 + 9.45414 -5.55274 + 5.63579 -5.55274 + 5.63579 -9.30342 + 7.70036 -9.30342 + 9.45414 -7.94566 + 16.77509 -5.12107 + 11.89382 -4.66241 + 11.89382 -12.45284 + 21.40626 -11.66909 + 21.40626 -5.61653 + -13.01982 -5.73995 + -14.81656 -7.61511 + -14.81656 -8.80096 + -11.00269 -8.80096 + -11.00269 -7.18731 + -12.59075 0.48701 + -22.72008 0.48701 + -22.72008 -3.21305 + -19.52924 -3.41157 + -22.25304 -6.62293 + -22.55761 -6.98298 + -22.54417 -7.39954 + -22.12761 -7.39954 + -18.23880 -9.92352 + -14.50705 -5.59707 + -17.38112 -3.31148 + -12.59075 -2.92074 + -25.94848 -0.04352 + -25.94848 -4.49621 + -24.44411 -4.49621 + -24.44411 -0.04352 + -9.47769 0.60169 + -9.47769 -5.94173 + -5.91345 -5.94173 + -5.91345 0.60169 + -2.93484 0.56001 + -2.93484 -2.12026 + -1.50451 -3.89600 + 1.52135 -3.89600 + 4.16885 -1.41298 + 4.16885 0.56001 + 6.49592 0.72149 + 6.49592 -2.43435 + 11.37711 -2.43435 + 11.37711 0.72149 + 13.98433 0.49463 + 13.98433 -2.30731 + 15.92389 -3.77146 + 18.21301 -3.77146 + 21.22329 -2.75141 + 21.22329 0.49463 + -25.94090 4.27844 + -25.94090 1.79756 + -24.25035 1.79756 + -24.25035 4.27844 + 23.72584 4.04178 + 23.72584 3.64399 + 24.12363 3.64399 + 24.12363 4.04178 + -9.09211 18.47720 + -9.09211 18.07941 + -8.69432 18.07941 + -8.69432 18.47720 + 7.65167 18.47708 + 7.65167 18.07930 + 8.04946 18.07930 + 8.04946 18.47708 + -2.01182 29.41857 + -2.01182 29.02078 + -1.61403 29.02078 + -1.61403 29.41857 + -16.70960 7.77674 + -21.12625 7.77674 + -21.12625 3.82276 + -20.29175 3.82276 + -16.70960 5.15741 + -13.94400 8.08194 + -13.94400 3.36081 + -9.48140 3.36081 + -9.48140 8.08194 + -7.05384 8.45622 + -7.05384 3.89796 + -3.90740 3.89796 + -3.90740 8.45622 + -1.38148 8.11511 + -1.38148 3.73587 + 4.62731 3.73587 + 4.62731 8.11511 + 7.70945 7.36558 + 7.70945 4.92616 + 8.85592 3.00637 + 11.77957 3.00637 + 11.77957 8.74681 + 9.44176 8.74681 + 15.26925 9.36141 + 15.26925 2.82294 + 18.65213 2.82294 + 18.65213 9.36141 + 20.86515 15.90490 + 20.86515 10.29087 + 26.15643 10.29087 + 26.15643 15.90490 + 14.16163 15.14089 + 14.16163 12.36089 + 18.76948 12.36089 + 18.76948 15.14089 + 8.15412 15.93415 + 8.15412 10.65574 + 11.23589 10.65574 + 11.23589 15.93415 + 4.78353 16.31064 + -0.10545 16.31064 + -2.03064 13.90512 + -2.03064 10.51702 + 0.85163 10.51702 + 4.78353 11.69502 + -6.90738 16.36030 + -6.90738 10.53811 + -3.63155 10.53811 + -3.63155 16.36030 + -14.05394 16.30070 + -14.05394 10.68666 + -9.00851 10.68666 + -9.00851 16.30070 + -15.39511 16.96411 + -18.79059 16.96411 + -21.18546 16.20817 + -21.18546 10.54530 + -16.98441 10.54530 + -15.39511 12.44016 + -25.99332 27.46643 + -25.99332 11.60336 + -23.96909 11.60336 + -23.96909 27.46643 + -25.94113 28.40401 + -24.59054 28.40401 + -22.91516 29.69436 + -22.81584 30.95893 + -21.15100 30.95893 + -19.94254 30.05464 + -17.01795 29.93370 + -2.92358 30.64587 + -2.92358 32.74006 + -22.08438 22.23176 + -22.08438 18.96659 + -18.03607 18.96659 + -18.03607 22.23176 + -14.95489 27.86244 + -14.95489 24.80378 + -11.85324 24.80378 + -11.85324 27.86244 + -15.98283 22.67341 + -17.25182 20.54588 + -17.02539 20.07997 + -15.27524 18.56568 + -13.14239 18.63172 + -11.75075 20.24036 + -12.14700 22.37617 + -14.00093 23.42817 + -9.06840 27.04534 + -9.06840 24.28593 + -7.94268 19.68062 + -4.48606 19.68062 + -2.95383 24.28593 + -2.95383 27.04534 + -0.74967 27.29233 + -0.74967 19.99572 + 4.49190 19.99572 + 4.49190 24.10701 + 2.68439 27.29233 + 6.72142 32.77541 + 6.72142 30.04308 + 13.87953 30.04308 + 13.87953 32.77541 + 7.15961 28.56717 + 7.15961 19.96875 + 11.87500 19.04461 + 13.26745 19.04461 + 13.26745 24.70949 + 10.42907 28.56717 + 22.21505 19.99581 + 24.74753 19.99581 + 24.04515 25.85913 + 24.04515 20.07695 + 25.25900 20.07695 + 25.25900 25.85913 + 15.14503 25.00994 + 15.14503 21.09383 + 22.41463 21.09383 + 22.41463 25.00994 + 16.54440 31.91924 + 15.14504 26.90949 + 22.48657 25.58098 + 23.52037 25.28422 + 24.11041 25.95569 + 22.30944 32.02001 + -22.41752 9.74716 + -22.41752 9.34937 + -22.01973 9.34937 + -22.01973 9.74716 + -15.34610 -30.02543 + -15.34610 -30.42322 + -14.94832 -30.42322 + -14.94832 -30.02543 + 18.65302 16.48025 + 18.65373 16.72453 + 18.40945 16.72521 + 18.40874 16.48093 + 15.44324 16.48059 + 15.70075 16.47992 + 15.70146 16.72419 + 15.44395 16.72487 + 17.66681 19.24892 + 17.38306 19.05148 + 17.71875 18.56909 + 18.00247 18.76652 + 15.95115 18.59142 + 15.60548 18.59242 + 15.60263 17.60910 + 15.94830 17.60810 + 18.65302 19.51844 + 18.65373 19.76272 + 18.40945 19.76339 + 18.40874 19.51912 + 15.44324 19.51945 + 15.70075 19.51878 + 15.70146 19.76306 + 15.44395 19.76374 + -20.02167 28.57323 + -20.14525 28.36251 + -19.93451 28.23896 + -19.81093 28.44968 + -17.24835 26.95726 + -17.47051 27.08746 + -17.59409 26.87675 + -17.37193 26.74654 + -20.56315 25.68447 + -20.21858 25.71224 + -20.26583 26.29804 + -20.61037 26.27026 + -18.74973 25.38900 + -18.45154 25.21414 + -17.95412 26.06237 + -18.25230 26.23723 + -21.55097 25.94800 + -21.67455 25.73728 + -21.46381 25.61374 + -21.34024 25.82445 + -18.77799 24.33145 + -19.00016 24.46165 + -19.12373 24.25094 + -18.90157 24.12073 + -4.43656 -6.49888 + -4.66244 -6.59191 + -4.56938 -6.81777 + -4.34351 -6.72475 + -3.20595 -9.46338 + -3.30408 -9.22530 + -3.52995 -9.31832 + -3.43182 -9.55640 + -6.61534 -8.47145 + -6.32418 -8.65780 + -6.00741 -8.16277 + -6.29855 -7.97646 + -5.35017 -9.80380 + -5.21853 -10.12342 + -4.30930 -9.74896 + -4.44094 -9.42933 + -7.24246 -7.66401 + -7.46834 -7.75703 + -7.37528 -7.98289 + -7.14940 -7.88987 + -6.01247 -10.62876 + -6.11060 -10.39069 + -6.33647 -10.48371 + -6.23835 -10.72179 + 6.17988 -10.76353 + 6.17916 -11.00782 + 6.42345 -11.00849 + 6.42416 -10.76421 + 9.38965 -10.76387 + 9.13215 -10.76320 + 9.13143 -11.00748 + 9.38894 -11.00815 + 7.16608 -13.53220 + 7.44984 -13.33477 + 7.11414 -12.85237 + 6.83042 -13.04980 + 8.88175 -12.87471 + 9.22742 -12.87570 + 9.23027 -11.89238 + 8.88460 -11.89138 + 6.17988 -13.80172 + 6.17916 -14.04600 + 6.42345 -14.04668 + 6.42416 -13.80240 + 9.38965 -13.80274 + 9.13215 -13.80206 + 9.13143 -14.04634 + 9.38894 -14.04702 + -19.38147 -18.25923 + -19.38218 -18.50352 + -19.13790 -18.50419 + -19.13719 -18.25991 + -16.17169 -18.25957 + -16.42920 -18.25890 + -16.42991 -18.50318 + -16.17241 -18.50385 + -18.39526 -21.02790 + -18.11151 -20.83047 + -18.44721 -20.34807 + -18.73092 -20.54550 + -16.67960 -20.37041 + -16.33393 -20.37140 + -16.33108 -19.38808 + -16.67675 -19.38708 + -19.38147 -21.29742 + -19.38218 -21.54170 + -19.13790 -21.54238 + -19.13719 -21.29810 + -16.17169 -21.29844 + -16.42920 -21.29776 + -16.42991 -21.54204 + -16.17241 -21.54272 + 23.09673 -32.60973 + 25.33933 -30.08445 + 25.35817 -25.69349 + 24.84935 -24.77007 + 24.41591 -24.75123 + 23.05904 -25.69349 + 22.98366 -30.55559 + 23.47201 -5.70815 + 23.47201 -2.65318 + 23.47201 -11.64627 + 18.59627 -30.82466 + 11.46920 -30.82466 + -0.44635 -27.01770 + -16.31527 -25.69694 + -24.15437 -18.70046 + -16.40676 -17.27451 + 11.89382 -10.78418 + 6.72414 34.00000 + -2.95155 34.00000 + -25.94112 32.66756 + -26.80000 34.00000 + 15.52374 34.00000 + 18.77983 21.09383 + -0.38024 -29.26214 + 1.18220 -29.88462 + 22.21505 15.97934 +419 + 131 143 41 45 + 182 281 128 130 + 115 413 146 154 + 32 44 25 263 + 38 86 281 284 + 164 165 189 190 + 86 420 282 283 + 398 402 160 179 + 47 93 31 317 + 178 220 229 230 + 240 244 106 119 + 383 391 46 307 + 117 377 149 150 + 59 71 167 168 + 95 98 32 316 + 357 360 89 92 + 99 456 321 323 + 28 455 258 320 + 253 255 80 82 + 261 270 122 135 + 433 440 16 23 + 6 440 7 23 + 266 272 101 125 + 384 393 53 57 + 36 457 260 267 + 119 121 152 153 + 239 282 129 133 + 206 209 183 186 + 23 26 140 141 + 133 390 43 306 + 222 328 217 218 + 154 201 112 305 + 155 205 180 181 + 207 235 185 192 + 135 197 298 301 + 127 410 287 290 + 268 362 93 123 + 57 60 254 257 + 110 412 146 155 + 218 340 332 333 + 152 389 304 306 + 7 37 6 261 + 203 238 110 113 + 184 230 210 213 + 400 460 291 293 + 135 151 300 301 + 85 142 12 274 + 212 214 191 195 + 196 241 102 105 + 159 162 153 182 + 360 369 89 90 + 135 194 297 298 + 334 336 227 234 + 28 54 255 256 + 169 452 244 250 + 333 345 234 327 + 37 442 3 6 + 41 421 272 280 + 379 386 52 59 + 218 324 329 330 + 190 290 207 209 + 50 91 139 319 + 266 271 79 125 + 18 48 137 318 + 214 223 195 219 + 34 437 2 5 + 266 371 77 79 + 137 139 66 73 + 327 329 220 226 + 20 27 322 324 + 21 26 140 322 + 66 446 171 172 + 426 435 18 20 + 231 286 133 204 + 52 70 166 168 + 212 228 194 195 + 108 392 51 54 + 326 339 223 225 + 204 233 113 184 + 236 243 111 127 + 241 248 102 103 + 262 290 207 308 + 283 286 200 201 + 192 318 71 74 + 51 62 252 259 + 17 114 144 145 + 253 349 82 87 + 185 229 199 212 + 118 122 147 152 + 356 366 76 83 + 407 412 155 157 + 2 45 25 29 + 125 167 241 295 + 268 355 121 123 + 160 161 182 183 + 326 330 223 226 + 298 306 215 313 + 398 411 163 179 + 144 146 299 303 + 60 449 253 254 + 287 295 203 211 + 58 449 245 254 + 146 152 300 302 + 260 353 99 120 + 428 438 4 17 + 68 128 248 296 + 64 177 242 243 + 154 155 108 112 + 124 126 293 294 + 30 35 260 262 + 160 206 180 183 + 252 316 69 70 + 385 392 53 54 + 103 106 34 42 + 6 433 22 23 + 221 304 232 240 + 226 230 193 213 + 276 281 130 132 + 306 311 215 236 + 409 416 176 286 + 297 337 224 237 + 218 225 330 331 + 430 432 13 14 + 380 394 44 50 + 29 53 165 256 + 288 294 202 203 + 17 23 142 164 + 131 144 45 116 + 141 148 11 273 + 84 85 274 284 + 265 272 101 117 + 65 448 246 247 + 110 118 147 148 + 89 101 19 49 + 263 370 76 77 + 2 322 24 26 + 185 226 199 213 + 74 322 8 26 + 130 146 302 303 + 358 363 92 97 + 404 418 158 174 + 425 459 279 283 + 222 229 196 198 + 271 361 91 93 + 174 317 68 71 + 109 395 48 55 + 422 435 13 18 + 253 263 75 81 + 150 173 64 67 + 6 102 27 277 + 297 344 235 237 + 373 383 58 307 + 375 377 61 150 + 140 149 11 66 + 223 228 195 196 + 5 46 29 30 + 19 47 317 318 + 260 267 120 122 + 30 79 266 275 + 108 385 52 54 + 247 252 70 72 + 207 208 186 192 + 422 426 18 276 + 237 242 109 111 + 432 441 14 16 + 217 219 228 231 + 105 380 44 47 + 251 317 68 69 + 153 388 304 307 + 7 33 265 267 + 236 281 128 129 + 267 352 120 121 + 336 345 233 234 + 247 319 70 74 + 34 438 2 4 + 253 365 81 84 + 381 393 50 57 + 355 362 100 123 + 30 40 262 275 + 110 397 147 155 + 116 157 114 151 + 66 447 172 247 + 218 325 329 333 + 307 342 334 335 + 326 335 325 326 + 180 243 127 134 + 421 431 10 272 + 128 453 248 251 + 127 409 286 287 + 256 259 86 95 + 0 445 169 171 + 229 296 198 212 + 101 132 19 40 + 292 299 214 215 + 429 441 14 15 + 130 144 116 303 + 22 418 158 177 + 41 436 270 272 + 34 40 5 262 + 8 11 28 33 + 9 10 28 34 + 59 65 167 245 + 12 49 35 39 + 246 264 72 78 + 111 376 143 149 + 19 97 317 321 + 203 204 113 115 + 5 94 30 32 + 12 15 36 39 + 170 176 228 242 + 41 86 281 282 + 245 265 78 118 + 155 202 112 181 + 89 143 12 19 + 181 236 127 128 + 378 387 59 60 + 39 83 269 271 + 271 368 79 91 + 87 102 277 278 + 326 334 225 325 + 6 434 21 22 + 200 237 109 110 + 354 363 97 100 + 126 163 162 295 + 337 344 233 237 + 105 390 43 47 + 332 346 327 335 + 120 126 162 294 + 188 284 205 206 + 334 339 225 227 + 27 50 319 320 + 350 354 96 97 + 161 210 183 188 + 2 32 24 25 + 96 97 316 317 + 268 278 93 124 + 107 113 37 62 + 22 115 144 154 + 136 193 65 297 + 53 70 165 166 + 132 143 19 41 + 277 280 124 132 + 351 353 96 99 + 189 285 205 208 + 16 21 138 140 + 225 327 220 330 + 380 390 46 47 + 13 107 37 38 + 349 359 87 94 + 331 338 197 222 + 222 297 197 198 + 303 308 315 336 + 202 205 115 181 + 361 368 90 91 + 282 286 133 201 + 241 249 103 106 + 341 466 334 337 + 195 197 104 298 + 263 366 76 85 + 359 367 83 87 + 123 399 159 178 + 381 384 56 57 + 56 61 257 258 + 332 343 328 335 + 151 198 301 305 + 63 449 170 253 + 27 92 319 324 + 284 285 200 205 + 357 369 88 89 + 204 234 184 185 + 164 211 188 190 + 191 196 102 104 + 293 465 216 311 + 170 216 221 228 + 427 434 20 21 + 262 462 308 309 + 270 279 131 135 + 356 370 76 88 + 63 450 170 252 + 240 275 119 134 + 422 430 10 13 + 6 427 21 277 + 24 29 141 165 + 1 305 239 240 + 298 307 312 313 + 156 372 108 114 + 163 166 189 295 + 297 338 197 224 + 179 276 126 130 + 28 55 255 258 + 374 378 60 61 + 104 105 42 43 + 41 420 280 282 + 22 404 156 158 + 136 173 65 67 + 18 49 39 137 + 265 273 117 118 + 15 18 39 138 + 67 177 229 243 + 65 449 245 246 + 46 93 30 31 + 8 33 264 265 + 297 347 235 312 + 330 339 222 223 + 259 348 95 98 + 34 428 3 4 + 175 219 228 230 + 307 346 314 335 + 165 215 190 221 + 104 133 40 43 + 309 312 236 315 + 190 289 208 209 + 187 261 206 207 + 88 101 49 278 + 122 396 147 159 + 137 149 63 66 + 64 170 242 244 + 232 239 136 187 + 11 42 33 35 + 38 458 271 284 + 40 437 5 270 + 191 248 74 102 + 335 340 326 328 + 397 407 155 161 + 87 424 277 279 + 382 387 56 60 + 225 329 217 220 + 428 439 9 17 + 199 200 107 109 + 405 408 173 175 + 119 158 151 153 + 39 79 269 275 + 403 410 288 290 + 213 227 192 194 + 174 193 65 71 + 289 291 202 209 + 108 112 52 62 + 20 100 323 324 + 423 425 276 283 + 300 308 336 337 + 183 287 210 211 + 259 351 98 99 + 105 394 44 48 + 112 379 52 143 + 25 419 177 292 + 350 358 94 97 + 431 436 9 272 + 405 417 173 174 + 16 23 140 142 + 17 22 144 164 + 211 215 190 191 + 33 43 263 264 + 399 401 160 178 + 252 264 72 75 + 65 72 167 248 + 121 162 153 162 + 32 323 1 24 + 31 320 0 1 + 402 411 179 288 + 263 365 81 85 + 198 201 107 305 + 290 461 308 311 + 256 349 82 95 + 14 113 37 145 + 25 127 285 292 + 406 411 163 175 + 7 443 6 7 + 199 242 105 109 + 108 395 51 55 + 24 70 165 285 + 61 454 258 259 + 129 451 250 251 + 10 106 34 38 + 1 315 239 310 + 127 416 286 292 + 80 83 268 269 + 69 127 285 296 + 428 442 3 15 + 8 43 33 264 + 217 224 219 231 + 13 14 36 37 + 291 294 202 214 + 127 403 290 291 + 22 414 154 156 + 84 141 273 274 + 303 313 238 315 + 129 169 249 250 + 134 152 302 306 + 408 417 173 176 + 244 274 118 119 + 9 103 27 34 + 300 341 332 337 + 222 331 197 218 + 125 168 241 249 + 186 296 211 212 + 310 465 216 310 + 111 117 148 149 + 325 340 326 333 + 75 321 0 8 + 398 406 161 163 + 219 224 231 331 + 233 238 113 136 + 269 280 124 131 + 230 287 204 210 + 404 415 156 157 + 227 235 192 193 + 307 347 312 314 + 31 77 0 266 + 153 373 108 307 + 261 284 135 206 + 7 36 261 267 + 116 375 114 150 + 231 239 133 187 + 136 150 63 67 + 124 400 289 293 + 253 364 84 87 + 123 401 178 289 + 180 275 126 134 + 374 382 58 60 +470 + 427 426 20 171 + 357 356 88 75 + 425 424 279 77 + 223 222 196 7 + 147 150 64 223 + 244 249 106 133 + 114 113 145 306 + 222 225 217 441 + 437 436 270 85 + 180 179 126 380 + 282 281 129 405 + 157 156 114 364 + 187 190 207 173 + 458 83 271 239 + 284 283 200 221 + 37 36 261 136 + 385 384 53 381 + 5 4 32 257 + 332 335 328 157 + 106 105 42 437 + 143 142 12 222 + 108 107 62 151 + 274 273 118 422 + 449 448 246 94 + 182 181 128 368 + 376 379 143 42 + 46 45 29 52 + 175 178 230 269 + 239 238 136 309 + 272 271 125 428 + 61 60 257 349 + 171 174 68 139 + 368 371 79 115 + 199 198 107 376 + 245 244 118 5 + 118 117 148 350 + 104 103 42 338 + 353 352 120 304 + 360 363 92 260 + 202 201 112 351 + 84 458 284 13 + 323 322 24 264 + 379 378 59 112 + 326 325 326 397 + 140 139 66 60 + 85 89 12 341 + 372 375 114 90 + 134 133 306 299 + 206 205 180 282 + 72 71 167 211 + 440 443 7 450 + 93 96 317 156 + 45 44 25 442 + 35 34 262 165 + 316 319 70 170 + 75 74 8 254 + 229 228 196 253 + 233 232 136 330 + 161 164 188 158 + 355 354 100 427 + 139 138 73 333 + 432 435 13 461 + 462 464 309 106 + 290 293 311 394 + 469 300 332 152 + 345 344 233 409 + 59 58 245 281 + 65 453 248 449 + 126 125 295 110 + 24 23 141 419 + 154 153 108 117 + 390 389 306 102 + 146 145 299 194 + 177 176 242 426 + 296 295 211 279 + 356 359 83 195 + 381 380 50 150 + 424 427 277 0 + 404 407 157 375 + 298 297 312 250 + 170 169 244 275 + 387 386 59 321 + 91 90 139 255 + 336 339 227 229 + 152 151 300 291 + 436 439 9 286 + 30 457 260 391 + 334 333 234 288 + 144 143 45 20 + 455 454 258 131 + 375 374 61 145 + 309 308 315 176 + 81 84 273 40 + 393 392 53 163 + 448 447 247 274 + 25 24 285 69 + 365 364 84 167 + 302 313 238 129 + 276 275 126 232 + 347 346 314 356 + 213 212 194 183 + 33 32 263 319 + 389 388 304 396 + 350 349 94 120 + 1 465 310 415 + 394 393 50 93 + 464 463 309 425 + 195 194 298 362 + 327 326 226 43 + 193 192 71 448 + 125 129 249 403 + 414 413 154 124 + 378 377 61 424 + 109 108 55 21 + 99 467 323 154 + 371 370 77 128 + 252 251 69 407 + 153 152 304 84 + 14 17 145 180 + 40 39 275 440 + 349 348 95 189 + 277 276 132 98 + 403 402 288 197 + 351 350 96 103 + 413 412 146 297 + 221 1 240 104 + 2 5 29 17 + 128 127 296 256 + 370 369 88 436 + 313 312 315 416 + 7 6 7 227 + 454 51 259 454 + 429 428 15 198 + 249 248 103 305 + 224 223 219 3 + 21 20 322 334 + 36 35 260 53 + 111 110 148 262 + 253 252 75 116 + 174 173 65 359 + 362 361 93 307 + 115 114 144 6 + 466 307 334 190 + 184 183 210 208 + 241 240 106 320 + 374 373 58 342 + 366 365 85 96 + 311 292 215 310 + 415 414 156 111 + 264 263 75 214 + 380 383 46 468 + 107 106 38 19 + 300 303 336 387 + 9 8 28 345 + 467 100 323 202 + 13 12 36 360 + 96 95 316 353 + 335 334 325 87 + 164 163 189 219 + 445 444 169 410 + 220 219 230 200 + 52 59 168 66 + 209 208 186 413 + 392 395 51 314 + 102 101 278 249 + 34 37 3 15 + 280 279 131 443 + 364 367 87 414 + 250 253 80 138 + 217 216 228 220 + 319 318 74 412 + 426 425 276 2 + 188 187 206 12 + 190 189 208 199 + 120 124 294 469 + 29 28 256 237 + 308 466 337 142 + 431 430 10 372 + 235 234 185 301 + 320 323 1 41 + 17 16 142 259 + 410 409 287 210 + 329 328 217 326 + 212 211 191 374 + 408 411 175 373 + 230 235 193 178 + 421 420 280 379 + 155 160 180 324 + 321 320 0 179 + 348 351 98 123 + 307 306 313 215 + 73 77 266 236 + 422 421 10 186 + 3 2 26 126 + 145 144 299 88 + 359 358 94 458 + 400 403 291 122 + 402 401 160 287 + 428 431 9 177 + 189 188 205 172 + 219 218 331 217 + 246 245 78 34 + 100 468 324 406 + 260 259 99 225 + 42 49 35 370 + 53 52 166 161 + 262 261 207 328 + 162 161 182 58 + 183 186 211 295 + 258 257 86 365 + 409 408 176 184 + 71 70 168 459 + 397 396 147 346 + 57 56 257 308 + 263 266 77 460 + 306 309 236 91 + 0 66 171 455 + 218 469 332 64 + 197 196 104 285 + 163 162 162 207 + 216 215 221 331 + 283 282 201 10 + 142 141 274 451 + 150 149 63 323 + 442 441 15 452 + 259 258 86 209 + 418 417 174 355 + 6 9 27 153 + 55 54 255 352 + 339 338 222 271 + 382 381 56 76 + 41 40 270 119 + 275 274 119 22 + 343 342 335 284 + 288 287 203 429 + 434 433 22 462 + 77 76 0 399 + 28 27 320 434 + 301 221 232 125 + 83 82 268 325 + 452 64 244 383 + 314 305 239 337 + 191 195 104 107 + 92 91 319 82 + 69 68 296 261 + 340 343 328 233 + 243 242 111 293 + 98 97 316 298 + 214 217 219 169 + 101 104 40 36 + 297 296 198 74 + 22 25 177 95 + 438 437 2 8 + 228 227 194 371 + 74 3 26 193 + 90 50 139 393 + 127 460 291 265 + 4 98 32 247 + 87 459 279 369 + 16 15 138 343 + 363 362 100 140 + 68 72 248 49 + 110 115 146 141 + 278 277 124 121 + 322 321 8 188 + 460 126 293 68 + 315 314 239 241 + 79 73 266 191 + 269 268 124 335 + 178 177 229 73 + 38 41 281 231 + 338 337 224 272 + 337 336 233 83 + 285 289 208 435 + 447 446 172 348 + 169 168 249 276 + 168 167 241 303 + 123 122 159 466 + 330 329 226 182 + 295 294 203 315 + 86 85 284 45 + 58 57 254 213 + 205 204 115 438 + 207 206 186 48 + 342 341 334 464 + 196 199 105 33 + 439 438 17 252 + 401 400 289 196 + 333 332 327 18 + 254 250 80 168 + 159 158 153 453 + 151 154 305 70 + 11 10 28 367 + 242 241 105 144 + 121 120 162 174 + 186 185 212 327 + 456 19 321 316 + 412 415 157 148 + 97 99 321 114 + 133 132 40 404 + 116 119 151 423 + 234 233 184 57 + 131 130 116 317 + 167 166 295 430 + 352 355 121 59 + 248 247 74 445 + 113 112 62 392 + 361 360 90 38 + 56 55 258 228 + 238 237 110 467 + 292 291 214 384 + 399 398 160 465 + 461 462 308 62 + 419 418 177 226 + 395 394 48 105 + 294 299 214 402 + 19 18 318 398 + 130 134 302 47 + 172 147 64 4 + 32 31 1 358 + 240 243 134 246 + 386 385 52 16 + 331 330 222 278 + 149 148 11 395 + 160 159 182 290 + 82 78 268 401 + 328 331 218 322 + 185 184 213 143 + 261 260 122 203 + 48 47 318 417 + 232 231 187 463 + 215 214 191 248 + 94 93 30 51 + 138 137 73 447 + 20 456 323 296 + 268 267 121 418 + 310 315 310 266 + 305 304 240 361 + 103 102 27 164 + 270 269 131 268 + 136 135 297 388 + 89 88 49 382 + 373 372 108 46 + 15 14 36 118 + 451 452 250 240 + 8 7 265 130 + 396 399 159 311 + 203 202 115 39 + 446 445 171 159 + 60 63 253 408 + 117 116 150 300 + 201 200 107 431 + 54 53 256 205 + 95 94 32 332 + 43 42 33 204 + 417 416 176 377 + 346 345 327 65 + 391 390 46 71 + 31 30 266 86 + 173 172 64 318 + 12 11 35 292 + 304 301 232 238 + 194 193 297 109 + 62 61 259 30 + 156 155 108 187 + 257 256 86 420 + 286 285 200 273 + 10 13 38 155 + 181 180 127 9 + 459 86 283 280 + 49 48 137 329 + 227 226 193 421 + 430 429 14 132 + 411 410 288 181 + 211 210 188 457 + 407 406 161 439 + 198 197 301 218 + 416 419 292 313 + 265 264 78 149 + 420 423 283 400 + 179 182 130 24 + 384 387 56 81 + 88 87 278 258 + 64 67 243 446 + 291 290 209 63 + 450 449 170 23 + 165 170 221 80 + 303 302 238 97 + 135 146 300 72 + 26 29 141 175 + 317 316 69 54 + 457 33 267 101 + 112 111 143 137 + 50 455 320 89 + 293 310 216 336 + 148 81 273 92 + 388 391 307 357 + 325 324 329 411 + 18 21 138 135 + 76 75 0 55 + 423 422 276 192 + 78 80 268 444 + 299 298 215 79 + 129 128 251 127 + 132 131 41 302 + 281 280 132 166 + 468 92 324 243 + 251 171 68 31 + 63 62 252 363 + 344 347 235 99 + 444 0 169 216 + 324 327 330 108 + 318 317 71 390 + 208 213 192 100 + 367 366 83 146 + 465 461 311 312 + 312 311 236 147 + 47 46 31 26 + 267 270 122 339 + 23 22 164 251 + 256 255 82 433 + 226 229 199 56 + 273 272 117 29 + 119 118 152 35 + 377 376 149 25 + 463 262 309 206 + 176 175 228 27 + 354 353 96 37 + 271 278 93 263 + 287 286 204 366 + 166 165 189 386 + 200 203 110 347 + 236 239 129 28 + 255 254 80 289 + 27 26 322 389 + 289 288 202 234 + 369 368 90 32 + 105 109 48 113 + 204 207 185 283 + 406 405 175 456 + 39 38 271 270 + 225 224 331 134 + 44 43 263 354 + 279 284 135 14 + 80 79 269 267 + 247 246 72 201 + 67 220 229 160 + 137 136 63 340 + 192 191 74 242 + 453 451 251 344 + 443 442 6 224 + 141 140 11 44 + 441 440 16 50 + 158 157 151 11 + 51 450 252 385 + 66 65 247 67 + 405 404 174 78 + 210 209 183 162 + 358 357 92 1 + 70 69 285 244 + 266 265 101 378 + 435 434 20 235 + 433 432 16 61 + 231 230 204 185 + 341 340 332 245 + 398 397 161 212 + 122 121 152 294 + 237 236 111 432 + 383 382 58 230 + 124 123 289 277 +defaultGrp +338 + -18.40464 -30.14798 + 6 31 77 76 75 321 320 + 0.00000 0.00000 0.00000 + 3 357 398 407 + 9 319 358 55 399 236 191 179 188 264 + + -15.73124 -29.53821 + 4 32 31 320 323 + 0.00000 0.00000 0.00000 + 2 356 357 + 6 319 358 101 179 188 41 + + -19.26803 -21.97476 + 3 34 438 437 + -0.00000 -0.00000 0.00000 + 2 65 174 + 5 53 165 8 252 286 + + -17.63033 -22.06259 + 4 428 34 37 442 + 0.00000 0.00000 0.00000 + 3 56 305 377 + 7 53 165 15 132 198 224 450 + + -18.93906 -21.80349 + 3 428 438 34 + -0.00000 0.00000 0.00000 + 3 104 174 305 + 6 53 165 132 198 252 286 + + -19.90440 -22.89651 + 3 437 40 34 + -0.00000 0.00000 0.00000 + 3 65 198 320 + 6 53 165 119 231 8 252 + + -15.77629 -22.54992 + 4 37 7 443 442 + 0.00000 0.00000 0.00000 + 3 41 56 366 + 7 130 345 15 165 224 450 50 + + -15.13138 -21.54972 + 4 6 440 443 7 + 0.00000 0.00000 0.00000 + 2 21 366 + 6 130 227 345 50 452 450 + + -15.89804 -31.15284 + 4 321 75 74 322 + 0.00000 0.00000 0.00000 + 2 137 398 + 6 55 254 399 188 264 41 + + -18.91121 -21.04223 + 4 431 436 439 428 + 0.00000 0.00000 0.00000 + 2 327 346 + 6 132 198 177 8 85 286 + + -18.92455 -19.47532 + 4 422 421 431 430 + 0.00000 0.00000 0.00000 + 2 186 280 + 6 186 192 400 177 372 198 + + -23.87359 -5.84374 + 4 148 141 140 149 + 0.00000 0.00000 0.00000 + 2 128 153 + 6 44 451 222 323 395 223 + + -20.13364 -9.71811 + 4 143 142 85 89 + 0.00000 0.00000 0.00000 + 2 46 213 + 6 45 280 341 20 222 88 + + -17.73536 -19.65244 + 4 435 422 430 432 + 0.00000 0.00000 0.00000 + 3 122 146 280 + 7 192 400 177 372 61 462 461 + + -17.41688 -20.71167 + 4 429 441 432 430 + 0.00000 0.00000 0.00000 + 3 122 164 194 + 7 132 372 177 61 462 224 452 + + -17.34147 -21.17454 + 4 429 428 442 441 + 0.00000 0.00000 0.00000 + 2 194 377 + 6 132 198 372 224 452 450 + + -16.40361 -20.83450 + 4 433 432 441 440 + 0.00000 0.00000 0.00000 + 2 20 164 + 6 61 462 235 50 452 224 + + -18.89012 -21.28946 + 3 439 438 428 + -0.00000 -0.00000 0.00000 + 2 104 327 + 5 132 198 252 286 85 + + -17.41485 -18.79815 + 3 422 435 426 + -0.00000 -0.00000 0.00000 + 3 72 146 162 + 6 192 400 0 171 61 461 + + -16.43727 -10.07712 + 4 143 89 101 132 + 0.00000 0.00000 0.00000 + 4 133 192 213 240 + 8 45 341 164 249 299 404 20 88 + + -16.40254 -18.94555 + 4 434 427 426 435 + 0.00000 0.00000 0.00000 + 2 72 274 + 6 0 171 77 235 461 61 + + -15.53139 -18.99165 + 3 6 427 434 + -0.00000 -0.00000 0.00000 + 3 220 274 281 + 6 130 227 0 77 235 461 + + -15.58524 -19.61417 + 3 6 434 433 + -0.00000 -0.00000 0.00000 + 2 114 220 + 5 130 227 235 462 461 + + -15.53211 -20.25095 + 3 433 440 6 + -0.00000 -0.00000 -0.00000 + 3 20 21 114 + 6 130 227 235 462 50 452 + + -13.38860 -30.13323 + 4 322 2 32 323 + 0.00000 0.00000 0.00000 + 3 135 233 356 + 7 126 193 101 319 41 264 179 + + -10.30839 -29.25856 + 4 44 32 2 45 + 0.00000 0.00000 0.00000 + 3 3 91 233 + 7 126 193 101 319 52 442 26 + + -13.54834 -31.73641 + 4 3 2 322 74 + 0.00000 0.00000 0.00000 + 2 135 137 + 6 126 193 254 55 41 264 + + -12.08217 -18.26643 + 4 9 103 102 6 + 0.00000 0.00000 0.00000 + 2 149 390 + 6 130 227 153 164 338 36 + + -9.09898 -21.21437 + 4 9 8 11 10 + 0.00000 0.00000 0.00000 + 2 199 200 + 6 153 345 227 292 367 360 + + -7.62496 -30.29785 + 4 5 46 45 2 + 0.00000 0.00000 0.00000 + 2 91 155 + 6 126 193 17 26 52 417 + + -4.65700 -30.03169 + 4 94 93 46 5 + 0.00000 0.00000 0.00000 + 3 155 207 300 + 7 17 126 26 417 51 332 353 + + -4.32256 -28.62127 + 3 93 47 46 + -0.00000 -0.00000 -0.00000 + 2 8 300 + 5 26 417 329 51 332 + + -3.84014 -31.28446 + 5 5 4 98 95 94 + 0.00000 0.00000 0.00000 + 2 14 207 + 7 17 257 126 332 353 156 247 + + -8.79478 -24.66238 + 4 42 11 8 43 + 0.00000 0.00000 0.00000 + 3 199 318 378 + 7 153 345 292 360 204 354 442 + + -9.15741 -18.04521 + 4 10 106 103 9 + 0.00000 0.00000 0.00000 + 4 113 200 372 390 + 8 153 227 292 367 36 338 19 151 + + -6.36226 -23.93125 + 4 42 49 12 11 + 0.00000 0.00000 0.00000 + 2 202 318 + 6 292 360 155 204 354 370 + + -4.25097 -20.56684 + 4 13 12 15 14 + 0.00000 0.00000 0.00000 + 2 208 380 + 6 155 360 367 118 343 259 + + -4.13355 -17.89736 + 4 107 13 14 113 + 0.00000 0.00000 0.00000 + 4 236 247 363 380 + 8 155 367 118 343 21 151 6 306 + + -6.69871 -17.82399 + 4 10 13 107 106 + 0.00000 0.00000 0.00000 + 2 247 372 + 6 292 367 155 19 151 21 + + -3.81787 -23.43359 + 4 12 49 18 15 + 0.00000 0.00000 0.00000 + 4 202 208 295 297 + 8 155 360 259 343 316 398 204 370 + + -12.46532 -9.80512 + 4 133 132 101 104 + 0.00000 0.00000 0.00000 + 2 192 309 + 6 164 249 36 299 404 47 + + -15.95731 -8.77987 + 3 132 131 143 + -0.00000 -0.00000 0.00000 + 2 0 240 + 5 302 404 299 20 88 + + -9.21583 -14.16812 + 4 105 104 103 106 + 0.00000 0.00000 0.00000 + 2 113 291 + 6 36 338 249 19 437 151 + + -9.20241 -9.72515 + 4 104 105 390 133 + 0.00000 0.00000 0.00000 + 4 29 225 291 309 + 8 36 249 19 437 47 299 71 357 + + -7.08282 -10.08754 + 3 105 394 380 + -0.00000 -0.00000 0.00000 + 3 123 166 342 + 6 19 437 76 150 105 314 + + -15.85414 -7.71190 + 3 143 131 144 + -0.00000 0.00000 0.00000 + 2 0 127 + 5 302 404 20 88 194 + + -6.85964 -8.08017 + 4 391 390 380 383 + 0.00000 0.00000 0.00000 + 2 11 246 + 6 76 150 468 71 357 396 + + -7.42909 -9.25394 + 3 105 380 390 + -0.00000 0.00000 0.00000 + 3 166 225 246 + 6 19 437 76 150 71 357 + + -6.97607 -10.95511 + 4 394 105 109 395 + 0.00000 0.00000 0.00000 + 2 145 342 + 6 19 437 113 105 314 163 + + -16.06402 -12.04633 + 3 88 101 89 + -0.00000 -0.00000 0.00000 + 2 133 313 + 5 341 382 45 164 249 + + -6.34665 -9.50091 + 4 394 393 381 380 + 0.00000 0.00000 0.00000 + 2 123 176 + 6 76 150 230 93 105 314 + + -5.84664 -11.22268 + 3 108 392 395 + -0.00000 -0.00000 0.00000 + 2 76 368 + 5 21 113 93 163 314 + + -4.19838 -10.89534 + 5 386 385 108 112 379 + 0.00000 0.00000 0.00000 + 4 58 159 336 343 + 9 21 113 306 392 25 42 16 321 81 + + -5.67294 -10.23667 + 4 393 392 385 384 + 0.00000 0.00000 0.00000 + 2 23 112 + 6 16 381 321 93 163 105 + + -5.50671 -11.02323 + 3 385 392 108 + -0.00000 -0.00000 0.00000 + 3 76 112 159 + 6 21 113 16 321 93 163 + + -6.18676 -11.44892 + 3 395 109 108 + -0.00000 -0.00000 0.00000 + 2 145 368 + 5 21 113 437 163 314 + + -5.53068 -9.01342 + 4 382 381 384 387 + 0.00000 0.00000 0.00000 + 2 261 325 + 6 76 230 468 16 381 81 + + -5.92832 -9.61743 + 3 384 381 393 + -0.00000 -0.00000 -0.00000 + 3 23 176 261 + 6 76 230 16 381 93 105 + + -5.38445 -7.38723 + 4 383 382 374 373 + 0.00000 0.00000 0.00000 + 2 151 418 + 6 145 342 90 230 468 150 + + -3.92800 -9.51326 + 4 386 379 378 387 + 0.00000 0.00000 0.00000 + 2 58 215 + 6 42 112 25 81 321 381 + + -4.63692 -8.43205 + 4 374 382 387 378 + 0.00000 0.00000 0.00000 + 4 215 290 325 418 + 8 90 145 42 112 230 468 81 381 + + -3.93673 -8.02154 + 4 378 377 375 374 + 0.00000 0.00000 0.00000 + 2 152 290 + 6 90 145 46 112 424 42 + + -4.01613 -14.83610 + 4 112 108 107 113 + 0.00000 0.00000 0.00000 + 2 236 336 + 6 21 151 113 306 392 6 + + -23.58209 -1.81644 + 4 150 149 137 136 + 0.00000 0.00000 0.00000 + 2 315 413 + 6 340 447 333 223 323 4 + + -25.14596 0.87702 + 4 172 147 150 173 + 0.00000 0.00000 0.00000 + 1 148 + 5 4 318 223 359 139 + + -23.08675 2.59644 + 4 173 136 193 174 + 0.00000 0.00000 0.00000 + 3 238 294 334 + 7 340 447 139 359 31 109 362 + + -22.99371 -5.32879 + 4 139 137 149 140 + 0.00000 0.00000 0.00000 + 3 67 153 315 + 7 333 447 44 60 451 223 323 + + -23.80484 0.74702 + 3 173 150 136 + -0.00000 0.00000 0.00000 + 3 148 294 413 + 6 340 447 4 223 139 359 + + -24.65052 7.37741 + 4 317 251 171 174 + 0.00000 0.00000 0.00000 + 2 144 167 + 6 31 407 139 116 390 412 + + -23.69936 10.57582 + 4 252 251 317 316 + 0.00000 0.00000 0.00000 + 2 111 167 + 6 116 407 138 54 390 412 + + -22.39795 10.41075 + 4 247 252 316 319 + 0.00000 0.00000 0.00000 + 3 111 160 173 + 7 305 445 116 138 54 390 170 + + -22.18802 6.91534 + 5 317 174 193 192 318 + 0.00000 0.00000 0.00000 + 3 83 144 334 + 8 31 139 109 448 362 390 412 170 + + -22.10610 14.33086 + 4 246 264 252 247 + 0.00000 0.00000 0.00000 + 3 160 203 353 + 7 201 445 305 116 138 149 378 + + -21.50079 -4.41585 + 3 139 138 137 + -0.00000 -0.00000 0.00000 + 1 67 + 4 333 447 60 44 + + -20.00753 9.29010 + 6 247 319 318 192 191 248 + 0.00000 0.00000 0.00000 + 3 83 173 321 + 9 242 448 109 305 445 133 170 412 54 + + -23.02674 20.06704 + 4 253 252 264 263 + 0.00000 0.00000 0.00000 + 2 147 353 + 6 116 138 168 149 214 378 + + -20.80877 24.44523 + 4 366 263 370 356 + 0.00000 0.00000 0.00000 + 4 89 134 258 277 + 8 149 214 1 75 146 414 115 128 + + -19.53644 23.20880 + 4 370 263 266 371 + 0.00000 0.00000 0.00000 + 2 66 134 + 6 149 214 460 115 128 32 + + -20.02412 17.77636 + 4 264 246 245 265 + 0.00000 0.00000 0.00000 + 2 203 211 + 6 34 201 445 149 378 460 + + -17.92461 23.33934 + 4 368 371 266 271 + 0.00000 0.00000 0.00000 + 3 62 66 217 + 7 214 460 29 428 32 436 115 + + -25.12352 27.93522 + 4 255 254 250 253 + 0.00000 0.00000 0.00000 + 1 18 + 5 168 289 138 433 420 + + -22.57601 25.14516 + 3 253 263 365 + -0.00000 -0.00000 0.00000 + 3 147 175 359 + 6 138 168 149 214 96 146 + + -22.90501 28.48183 + 4 253 349 256 255 + 0.00000 0.00000 0.00000 + 3 18 86 362 + 7 138 168 420 433 365 103 120 + + -20.99439 25.84823 + 4 367 366 356 359 + 0.00000 0.00000 0.00000 + 2 89 259 + 6 1 75 195 146 414 167 + + -22.39820 26.38390 + 3 365 364 253 + -0.00000 0.00000 0.00000 + 2 175 415 + 5 138 168 96 167 146 + + -21.74091 24.52759 + 3 366 365 263 + -0.00000 0.00000 -0.00000 + 2 258 359 + 5 149 214 96 146 414 + + -21.70614 30.41671 + 4 258 257 256 259 + 0.00000 0.00000 0.00000 + 1 189 + 5 365 420 209 225 203 + + -21.52318 26.77433 + 5 364 367 359 349 253 + 0.00000 0.00000 0.00000 + 4 86 248 259 415 + 9 138 168 103 120 75 195 96 167 414 + + -19.72640 25.02732 + 4 357 356 370 369 + 0.00000 0.00000 0.00000 + 2 268 277 + 6 1 75 458 128 436 115 + + -19.32282 25.18763 + 3 357 369 360 + -0.00000 0.00000 0.00000 + 3 15 50 268 + 6 1 458 38 307 128 436 + + -18.74485 24.84906 + 4 361 360 369 368 + 0.00000 0.00000 0.00000 + 2 50 253 + 6 38 307 140 32 436 128 + + -17.73745 24.07300 + 3 361 368 271 + -0.00000 0.00000 -0.00000 + 3 143 217 253 + 6 29 428 140 307 32 436 + + -19.37161 25.90913 + 4 358 357 360 363 + 0.00000 0.00000 0.00000 + 2 15 139 + 6 1 458 195 38 307 260 + + -16.26886 24.43638 + 5 268 362 361 271 278 + 0.00000 0.00000 0.00000 + 3 36 143 235 + 8 268 335 29 428 263 140 307 260 + + -20.23899 27.29244 + 4 350 349 359 358 + 0.00000 0.00000 0.00000 + 2 248 345 + 6 103 120 123 195 458 75 + + -20.75615 29.17118 + 4 348 259 256 349 + 0.00000 0.00000 0.00000 + 3 189 304 362 + 7 365 420 203 225 120 189 103 + + -18.70251 27.66321 + 4 351 350 354 353 + 0.00000 0.00000 0.00000 + 2 231 242 + 6 103 123 189 37 427 59 + + -19.01168 26.91274 + 4 350 358 363 354 + 0.00000 0.00000 0.00000 + 4 139 222 231 345 + 8 103 123 59 427 195 458 38 260 + + -19.92505 29.02585 + 3 259 348 351 + -0.00000 0.00000 0.00000 + 2 304 341 + 5 203 225 120 189 123 + + -18.56049 28.88137 + 4 260 259 351 353 + 0.00000 0.00000 0.00000 + 3 103 242 341 + 7 203 225 328 123 189 37 427 + + -17.79311 26.48072 + 4 354 363 362 355 + 0.00000 0.00000 0.00000 + 2 177 222 + 6 59 427 304 140 260 38 + + -17.77465 20.58141 + 3 266 265 272 + -0.00000 -0.00000 0.00000 + 2 22 130 + 5 378 460 214 29 422 + + -15.42299 9.27266 + 4 248 191 196 241 + 0.00000 0.00000 0.00000 + 4 48 80 271 321 + 8 242 448 218 285 144 293 133 305 + + -15.47782 11.22404 + 3 241 249 248 + -0.00000 0.00000 0.00000 + 2 80 255 + 5 144 293 133 305 5 + + -15.32680 6.09423 + 4 196 191 195 197 + 0.00000 0.00000 0.00000 + 2 257 271 + 6 242 448 107 218 285 376 + + -11.62196 9.38430 + 4 241 196 199 242 + 0.00000 0.00000 0.00000 + 2 48 367 + 6 218 285 33 144 293 246 + + -14.72452 14.09791 + 4 249 241 240 244 + 0.00000 0.00000 0.00000 + 2 10 255 + 6 144 320 293 5 34 133 + + -8.26762 5.94923 + 4 199 198 201 200 + 0.00000 0.00000 0.00000 + 2 328 360 + 6 33 376 285 351 431 39 + + -4.46593 -3.33185 + 6 153 373 372 156 155 154 + 0.00000 0.00000 0.00000 + 3 107 285 408 + 9 70 117 291 187 364 11 46 342 145 + + -8.11278 9.44073 + 4 242 199 200 237 + 0.00000 0.00000 0.00000 + 4 163 221 328 367 + 8 33 285 351 431 309 467 246 293 + + -5.37504 9.49716 + 4 237 200 203 238 + 0.00000 0.00000 0.00000 + 2 42 221 + 6 351 431 347 309 467 28 + + -7.95795 13.47144 + 4 242 237 236 243 + 0.00000 0.00000 0.00000 + 2 79 163 + 6 432 467 309 246 293 320 + + -4.95238 2.23941 + 4 154 155 202 201 + 0.00000 0.00000 0.00000 + 3 31 107 212 + 7 70 291 187 364 39 351 347 + + -2.73777 9.40661 + 4 233 238 203 204 + 0.00000 0.00000 0.00000 + 4 42 78 206 401 + 8 347 431 282 438 57 301 28 309 + + -3.08852 -5.06489 + 5 372 375 116 157 156 + 0.00000 0.00000 0.00000 + 3 180 285 411 + 8 300 350 11 364 453 46 342 90 + + -2.64444 6.05129 + 4 204 203 202 205 + 0.00000 0.00000 0.00000 + 2 206 252 + 6 39 347 431 282 438 48 + + -14.11448 -6.31738 + 3 130 144 131 + -0.00000 0.00000 0.00000 + 2 127 195 + 5 302 317 404 88 194 + + -17.43776 19.86415 + 3 272 265 273 + -0.00000 0.00000 0.00000 + 2 130 296 + 5 378 460 29 422 22 + + -16.90448 18.30809 + 5 274 273 265 245 244 + 0.00000 0.00000 0.00000 + 3 211 296 389 + 8 5 34 201 378 460 22 422 232 + + -14.46667 17.61555 + 4 274 244 240 275 + 0.00000 0.00000 0.00000 + 3 10 279 389 + 7 144 320 5 34 22 232 98 + + -16.67293 27.96022 + 4 260 353 352 267 + 0.00000 0.00000 0.00000 + 3 103 157 171 + 7 203 328 335 418 37 304 427 + + -16.13251 26.59251 + 4 352 355 268 267 + 0.00000 0.00000 0.00000 + 2 93 171 + 6 335 418 268 37 304 59 + + -11.68742 29.07611 + 4 260 267 270 261 + 0.00000 0.00000 0.00000 + 2 19 157 + 6 203 328 206 335 418 339 + + -16.76031 25.87090 + 3 268 355 362 + -0.00000 0.00000 -0.00000 + 3 36 93 177 + 6 268 335 59 304 140 260 + + -12.40489 23.93957 + 5 269 268 278 277 280 + 0.00000 0.00000 0.00000 + 3 235 241 402 + 8 268 335 339 121 263 428 166 405 + + -17.09024 21.81702 + 3 266 272 271 + -0.00000 0.00000 0.00000 + 2 22 62 + 5 214 460 29 428 422 + + -10.76934 18.85717 + 4 275 180 179 276 + 0.00000 0.00000 0.00000 + 2 288 417 + 6 9 380 368 98 232 121 + + -8.42558 17.20495 + 4 181 180 243 236 + 0.00000 0.00000 0.00000 + 3 79 185 214 + 7 9 368 24 432 467 246 320 + + -8.05967 18.14938 + 4 181 236 281 182 + 0.00000 0.00000 0.00000 + 3 1 170 214 + 7 24 368 380 432 467 10 405 + + -5.74192 18.02046 + 4 236 239 282 281 + 0.00000 0.00000 0.00000 + 2 26 170 + 6 432 467 28 10 405 221 + + -9.36996 19.21884 + 4 179 182 281 276 + 0.00000 0.00000 0.00000 + 3 1 117 288 + 7 9 380 24 98 121 10 405 + + -10.46082 25.99937 + 4 279 270 269 280 + 0.00000 0.00000 0.00000 + 2 276 402 + 6 268 339 418 166 443 405 + + -10.22721 21.64577 + 4 280 277 276 281 + 0.00000 0.00000 0.00000 + 2 117 241 + 6 98 121 263 166 405 10 + + -2.24318 18.08682 + 4 286 282 239 231 + 0.00000 0.00000 0.00000 + 4 26 73 254 412 + 8 330 463 28 432 10 221 366 429 + + -11.32424 17.32813 + 4 243 180 275 240 + 0.00000 0.00000 0.00000 + 3 185 279 417 + 7 9 368 144 320 246 98 232 + + -6.69976 28.14975 + 4 261 270 279 284 + 0.00000 0.00000 0.00000 + 3 19 276 409 + 7 206 328 339 418 166 443 14 + + -2.83110 12.83014 + 4 232 239 238 233 + 0.00000 0.00000 0.00000 + 2 317 401 + 6 57 330 301 28 309 432 + + -3.31914 -25.01865 + 3 48 18 49 + -0.00000 -0.00000 -0.00000 + 2 63 295 + 5 316 398 329 370 204 + + 0.91455 -22.93593 + 4 16 15 18 21 + 0.00000 0.00000 0.00000 + 2 244 297 + 6 259 343 180 316 398 135 + + 5.21826 -31.73178 + 3 91 90 50 + 0.00000 -0.00000 0.00000 + 1 61 + 4 255 393 82 243 + + 5.45955 -23.11717 + 4 16 21 26 23 + 0.00000 0.00000 0.00000 + 4 28 70 244 348 + 8 180 259 135 398 69 419 389 434 + + 8.58505 -23.29841 + 4 24 23 26 29 + 0.00000 0.00000 0.00000 + 2 28 282 + 6 69 419 95 389 434 175 + + 5.43674 -20.91100 + 3 17 16 23 + 0.00000 -0.00000 0.00000 + 2 126 348 + 5 180 259 118 69 419 + + -2.66597 -10.63802 + 4 111 376 379 112 + 0.00000 0.00000 0.00000 + 2 204 343 + 6 137 392 306 25 424 42 + + 3.90555 -16.92938 + 4 115 114 17 22 + 0.00000 0.00000 0.00000 + 3 85 237 349 + 7 118 180 251 419 6 141 262 + + -0.20712 -17.97073 + 4 114 113 14 17 + 0.00000 0.00000 0.00000 + 2 85 363 + 6 118 343 180 6 306 141 + + 4.85698 -13.57062 + 4 412 110 115 413 + 0.00000 0.00000 0.00000 + 2 2 38 + 6 137 262 141 124 297 111 + + 5.05216 -10.23380 + 5 122 118 110 397 396 + 0.00000 0.00000 0.00000 + 4 88 132 179 314 + 9 137 262 35 423 277 466 212 346 465 + + 0.93996 -10.04712 + 4 111 110 118 117 + 0.00000 0.00000 0.00000 + 2 132 396 + 6 137 262 392 35 350 423 + + -2.50404 -9.69573 + 4 117 377 376 111 + 0.00000 0.00000 0.00000 + 3 12 204 396 + 7 137 392 35 350 25 424 112 + + -3.02348 -7.83174 + 4 377 117 116 375 + 0.00000 0.00000 0.00000 + 3 12 152 411 + 7 300 350 35 46 90 112 424 + + 0.38130 -4.99028 + 4 116 119 158 157 + 0.00000 0.00000 0.00000 + 2 180 330 + 6 300 350 423 11 453 290 + + 4.68365 -7.55827 + 4 119 118 122 121 + 0.00000 0.00000 0.00000 + 2 25 88 + 6 35 423 300 294 466 277 + + 4.31069 -3.87613 + 5 159 158 119 121 162 + 0.00000 0.00000 0.00000 + 4 25 49 330 355 + 9 300 423 294 466 290 453 324 207 219 + + 5.75382 -14.96719 + 4 22 414 413 115 + 0.00000 0.00000 0.00000 + 3 2 237 383 + 7 251 419 141 262 111 124 148 + + 5.68098 -12.16530 + 4 397 110 412 407 + 0.00000 0.00000 0.00000 + 4 38 90 179 323 + 8 137 262 212 465 78 375 124 297 + + 6.72298 -14.38112 + 4 404 415 414 22 + 0.00000 0.00000 0.00000 + 3 293 383 404 + 7 251 419 78 456 111 148 297 + + 6.65014 -13.54653 + 4 415 404 407 412 + 0.00000 0.00000 0.00000 + 2 90 404 + 6 78 456 375 124 297 148 + + 7.72525 -14.57391 + 3 404 22 418 + 0.00000 -0.00000 0.00000 + 3 140 196 293 + 6 251 419 78 456 226 313 + + 6.48504 -10.03364 + 4 122 396 399 123 + 0.00000 0.00000 0.00000 + 2 260 314 + 6 277 466 469 212 346 311 + + 7.77780 -10.88584 + 4 399 398 402 401 + 0.00000 0.00000 0.00000 + 2 7 352 + 6 311 465 346 197 287 122 + + 6.63679 -11.97962 + 4 398 397 407 406 + 0.00000 0.00000 0.00000 + 2 323 399 + 6 212 465 311 375 439 78 + + 8.97135 -4.12732 + 5 162 121 120 126 163 + 0.00000 0.00000 0.00000 + 3 223 227 355 + 8 174 294 466 68 265 207 219 158 + + 7.47406 -11.91742 + 3 406 411 398 + 0.00000 -0.00000 0.00000 + 3 97 365 399 + 6 311 465 375 439 184 373 + + 6.15749 -18.95315 + 3 17 23 22 + 0.00000 0.00000 0.00000 + 2 126 349 + 5 118 180 251 419 69 + + 12.60059 -23.07096 + 4 29 53 70 24 + 0.00000 0.00000 0.00000 + 4 124 239 282 369 + 8 69 95 175 389 205 352 211 459 + + 15.07081 -22.91162 + 3 53 52 70 + 0.00000 -0.00000 0.00000 + 2 74 239 + 5 161 205 352 211 459 + + 19.86861 -21.20681 + 4 72 71 59 65 + 0.00000 0.00000 0.00000 + 3 13 201 354 + 7 66 161 67 455 49 211 261 + + 16.53049 -22.20105 + 4 52 59 71 70 + 0.00000 0.00000 0.00000 + 2 13 74 + 6 161 205 66 211 459 49 + + 25.07869 -31.89806 + 3 444 0 445 + 0.00000 -0.00000 0.00000 + 1 190 + 4 216 410 159 348 + + 22.43204 -27.82560 + 3 450 449 63 + 0.00000 -0.00000 0.00000 + 2 265 278 + 5 349 408 23 385 454 + + 25.92903 -27.50402 + 4 446 445 0 66 + 0.00000 0.00000 0.00000 + 2 71 190 + 6 216 410 455 159 348 274 + + 25.47538 -23.90057 + 3 66 447 446 + 0.00000 -0.00000 0.00000 + 2 71 181 + 5 216 455 274 348 94 + + 8.48791 -13.33718 + 3 408 405 417 + 0.00000 -0.00000 0.00000 + 3 329 347 388 + 6 439 456 184 210 226 355 + + 8.21988 -13.67884 + 4 405 404 418 417 + 0.00000 0.00000 0.00000 + 2 140 347 + 6 78 456 439 226 355 313 + + 8.08258 -12.73831 + 4 408 411 406 405 + 0.00000 0.00000 0.00000 + 2 329 365 + 6 439 456 375 184 210 373 + + 9.15774 -13.33880 + 4 409 408 417 416 + 0.00000 0.00000 0.00000 + 2 119 388 + 6 184 210 181 355 377 226 + + 8.90285 -15.09494 + 4 25 419 418 22 + 0.00000 0.00000 0.00000 + 2 196 344 + 6 251 419 95 226 313 377 + + 7.75222 -10.27694 + 3 123 399 401 + 0.00000 -0.00000 0.00000 + 3 260 352 416 + 6 277 469 311 346 197 287 + + 8.14649 -11.30245 + 3 398 411 402 + 0.00000 -0.00000 -0.00000 + 3 7 97 358 + 6 311 465 122 197 184 373 + + 1.11996 2.14794 + 4 205 155 160 206 + 0.00000 0.00000 0.00000 + 2 32 110 + 6 187 364 324 48 282 283 + + -2.74124 2.73128 + 3 202 155 205 + -0.00000 -0.00000 0.00000 + 3 32 212 252 + 6 187 364 39 347 48 282 + + 5.33239 -0.64146 + 4 161 160 159 162 + 0.00000 0.00000 0.00000 + 2 49 94 + 6 290 324 187 58 207 219 + + 6.37149 2.58998 + 5 206 160 161 210 209 + 0.00000 0.00000 0.00000 + 4 27 94 110 232 + 9 187 324 58 207 48 283 162 457 374 + + -0.85350 9.71638 + 3 233 204 234 + -0.00000 0.00000 0.00000 + 2 78 269 + 5 282 438 57 301 178 + + 2.22025 9.61056 + 4 234 204 207 235 + 0.00000 0.00000 0.00000 + 2 33 269 + 6 282 438 283 178 301 185 + + 6.16838 6.03568 + 4 209 208 207 206 + 0.00000 0.00000 0.00000 + 2 27 161 + 6 48 283 438 162 413 457 + + -1.92255 15.52535 + 3 239 232 231 + -0.00000 0.00000 0.00000 + 2 317 412 + 5 330 463 57 28 432 + + 9.62713 1.86394 + 4 210 161 164 211 + 0.00000 0.00000 0.00000 + 2 232 270 + 6 58 207 158 374 457 183 + + 12.68072 -0.88138 + 4 165 164 163 166 + 0.00000 0.00000 0.00000 + 2 5 286 + 6 158 219 58 386 430 303 + + 13.10256 1.76136 + 4 165 215 211 164 + 0.00000 0.00000 0.00000 + 4 5 270 308 350 + 8 58 158 386 430 183 374 220 331 + + 13.52441 5.98438 + 4 212 211 215 214 + 0.00000 0.00000 0.00000 + 2 47 350 + 6 183 374 100 248 331 220 + + 6.94323 9.31565 + 5 208 213 227 235 207 + 0.00000 0.00000 0.00000 + 4 33 161 333 405 + 9 283 438 162 413 100 253 371 178 185 + + 6.46882 13.64889 + 4 226 230 235 227 + 0.00000 0.00000 0.00000 + 2 116 405 + 6 371 421 253 185 463 178 + + 10.15283 9.70128 + 4 228 227 213 212 + 0.00000 0.00000 0.00000 + 2 75 333 + 6 100 183 413 253 371 56 + + 13.11159 10.28121 + 4 214 223 228 212 + 0.00000 0.00000 0.00000 + 4 47 64 75 154 + 8 100 183 248 331 3 134 56 253 + + 12.69876 13.52292 + 4 223 222 229 228 + 0.00000 0.00000 0.00000 + 2 142 154 + 6 3 7 134 56 253 421 + + 14.61891 17.12987 + 4 297 222 331 338 + 0.00000 0.00000 0.00000 + 4 249 250 287 392 + 8 3 7 79 250 322 326 229 271 + + 12.63499 17.29107 + 4 229 222 297 296 + 0.00000 0.00000 0.00000 + 3 142 191 250 + 7 3 7 56 421 74 250 79 + + 9.14649 16.64920 + 3 185 226 229 + 0.00000 0.00000 0.00000 + 2 87 136 + 5 295 327 371 421 56 + + -1.85175 24.65483 + 4 285 284 283 286 + 0.00000 0.00000 0.00000 + 2 82 267 + 6 14 221 443 273 366 429 + + -2.72985 21.32076 + 3 283 282 286 + -0.00000 0.00000 -0.00000 + 2 82 254 + 5 10 221 14 366 429 + + 5.26433 27.50240 + 4 289 288 294 291 + 0.00000 0.00000 0.00000 + 3 125 335 381 + 7 234 435 273 310 384 279 315 + + 5.82576 23.15966 + 4 288 287 295 294 + 0.00000 0.00000 0.00000 + 2 100 125 + 6 234 429 435 279 315 74 + + 2.10508 18.15318 + 4 287 286 231 230 + 0.00000 0.00000 0.00000 + 2 73 403 + 6 185 463 330 366 429 234 + + -1.83234 28.09481 + 4 188 284 285 189 + 0.00000 0.00000 0.00000 + 3 228 243 267 + 7 172 199 173 14 443 273 366 + + -2.47526 29.03264 + 4 188 187 261 284 + 0.00000 0.00000 0.00000 + 3 228 312 409 + 7 12 172 199 206 328 14 443 + + -0.55032 30.99970 + 5 190 290 262 261 187 + 0.00000 0.00000 0.00000 + 3 60 81 312 + 8 12 172 173 206 328 425 63 384 + + -0.32333 28.25600 + 4 190 189 285 289 + 0.00000 0.00000 0.00000 + 2 243 311 + 6 173 199 12 273 366 435 + + 3.62830 29.88235 + 4 290 190 289 291 + 0.00000 0.00000 0.00000 + 3 60 311 335 + 7 12 173 273 435 63 384 310 + + 6.14470 18.21569 + 4 287 230 184 183 + 0.00000 0.00000 0.00000 + 3 43 340 403 + 7 143 208 327 185 463 234 429 + + 7.84553 19.19265 + 5 295 287 183 186 296 + 0.00000 0.00000 0.00000 + 3 100 340 394 + 8 143 208 295 234 429 74 279 250 + + 9.80245 17.88379 + 4 296 186 185 229 + 0.00000 0.00000 0.00000 + 3 87 191 394 + 7 295 327 208 56 421 74 250 + + 7.15970 17.10085 + 4 226 185 184 230 + 0.00000 0.00000 0.00000 + 3 43 116 136 + 7 143 327 295 371 421 185 463 + + 9.54741 29.30512 + 4 299 292 291 294 + 0.00000 0.00000 0.00000 + 2 193 381 + 6 310 384 147 279 315 402 + + 13.57322 27.04784 + 5 311 292 299 298 306 + 0.00000 0.00000 0.00000 + 3 96 118 193 + 8 147 310 79 402 315 190 215 416 + + 15.31589 32.89822 + 3 293 310 465 + 0.00000 0.00000 -0.00000 + 2 272 395 + 5 63 394 336 104 415 + + 16.01877 15.81057 + 4 329 328 222 225 + 0.00000 0.00000 0.00000 + 2 30 326 + 6 3 7 441 182 326 278 + + 15.01628 16.11545 + 3 328 331 222 + 0.00000 -0.00000 0.00000 + 2 30 392 + 5 3 7 182 326 322 + + 16.71312 10.86115 + 4 224 223 214 217 + 0.00000 0.00000 0.00000 + 2 64 379 + 6 248 331 169 3 134 441 + + 17.62632 16.03391 + 3 329 225 327 + 0.00000 0.00000 -0.00000 + 3 68 245 326 + 6 7 441 108 411 182 278 + + 17.28225 1.65879 + 4 216 215 165 170 + 0.00000 0.00000 0.00000 + 2 273 308 + 6 386 430 80 220 331 169 + + 15.67408 17.16657 + 4 338 331 330 339 + 0.00000 0.00000 0.00000 + 2 249 303 + 6 278 322 326 229 271 83 + + 16.68640 17.01917 + 3 330 326 339 + 0.00000 0.00000 0.00000 + 3 77 95 303 + 6 43 108 278 322 83 229 + + 14.82518 18.41538 + 3 338 337 297 + 0.00000 0.00000 0.00000 + 2 120 287 + 5 79 250 271 272 229 + + 17.35883 17.63413 + 3 334 339 326 + 0.00000 0.00000 -0.00000 + 3 77 219 229 + 6 43 108 87 157 83 229 + + 17.05510 16.60256 + 4 327 326 330 329 + 0.00000 0.00000 0.00000 + 2 68 95 + 6 43 108 411 182 278 322 + + 16.53940 18.25620 + 3 336 339 334 + 0.00000 0.00000 0.00000 + 2 52 229 + 5 87 157 83 272 229 + + 21.14073 5.10927 + 6 217 216 170 176 175 219 + 0.00000 0.00000 0.00000 + 4 165 209 273 306 + 10 80 386 27 426 73 169 220 248 160 200 + + 25.15558 4.59461 + 4 178 177 67 220 + 0.00000 0.00000 0.00000 + 2 9 298 + 6 383 446 73 269 27 160 + + 23.71776 7.16633 + 4 175 178 220 219 + 0.00000 0.00000 0.00000 + 2 9 306 + 6 27 426 269 160 200 446 + + 19.42892 10.67106 + 3 224 217 219 + 0.00000 0.00000 0.00000 + 3 165 379 400 + 6 169 248 160 200 134 441 + + 25.38765 18.65922 + 3 301 221 304 + 0.00000 0.00000 -0.00000 + 1 115 + 4 125 238 361 337 + + 15.67515 19.05552 + 4 337 336 345 344 + 0.00000 0.00000 0.00000 + 2 172 224 + 6 83 272 271 65 409 356 + + 16.68843 18.93269 + 4 333 345 336 334 + 0.00000 0.00000 0.00000 + 3 52 55 172 + 7 87 288 157 83 272 65 356 + + 14.71821 19.44260 + 3 344 347 297 + 0.00000 0.00000 0.00000 + 2 150 302 + 5 79 250 65 409 99 + + 18.79782 25.62759 + 4 312 311 306 309 + 0.00000 0.00000 0.00000 + 2 118 310 + 6 190 215 91 147 416 129 + + 14.77205 19.05216 + 3 297 337 344 + 0.00000 0.00000 -0.00000 + 3 120 150 224 + 6 79 250 271 272 65 409 + + 23.87022 23.74010 + 3 302 313 303 + 0.00000 -0.00000 0.00000 + 1 385 + 4 97 387 152 129 + + 24.61971 29.45871 + 4 315 314 305 1 + 0.00000 0.00000 0.00000 + 2 283 373 + 6 104 125 241 337 266 336 + + 25.86861 23.96025 + 4 305 304 221 1 + 0.00000 0.00000 0.00000 + 2 115 283 + 6 104 125 238 337 361 241 + + 16.97067 -4.22133 + 3 125 168 167 + 0.00000 -0.00000 0.00000 + 2 92 393 + 5 68 110 276 303 275 + + 23.13619 2.04611 + 4 176 170 64 177 + 0.00000 0.00000 0.00000 + 3 106 209 316 + 7 240 383 80 386 73 426 269 + + 24.60475 1.48253 + 3 177 64 67 + 0.00000 0.00000 0.00000 + 2 106 298 + 5 240 383 446 73 269 + + 22.34765 -1.12704 + 4 169 452 64 170 + 0.00000 0.00000 0.00000 + 2 54 316 + 6 240 383 80 275 386 344 + + 21.04089 -23.80507 + 4 65 59 58 449 + 0.00000 0.00000 0.00000 + 3 101 201 299 + 7 66 281 161 67 455 23 385 + + 23.64899 -23.89429 + 3 65 449 448 + 0.00000 0.00000 0.00000 + 2 131 299 + 5 67 455 23 94 385 + + 24.73897 -22.99940 + 4 447 66 65 448 + 0.00000 0.00000 0.00000 + 2 131 181 + 6 67 455 216 94 274 23 + + 21.84604 -15.50597 + 5 68 72 65 453 128 + 0.00000 0.00000 0.00000 + 3 105 187 354 + 8 67 455 244 261 49 127 403 449 + + 19.40441 -4.31512 + 4 168 125 129 169 + 0.00000 0.00000 0.00000 + 2 386 393 + 6 68 110 403 275 276 80 + + 22.39339 -4.18232 + 4 452 169 129 451 + 0.00000 0.00000 0.00000 + 3 54 371 386 + 7 110 403 80 275 344 449 240 + + 22.43914 -8.66001 + 4 451 129 128 453 + 0.00000 0.00000 0.00000 + 2 187 371 + 6 127 403 110 344 449 67 + + 21.55540 -29.36308 + 4 450 63 62 51 + 0.00000 0.00000 0.00000 + 2 84 278 + 6 131 454 363 408 349 385 + + 21.60304 -26.42208 + 3 60 63 449 + 0.00000 -0.00000 0.00000 + 2 99 265 + 5 30 349 408 23 385 + + 20.57877 -25.80841 + 4 60 449 58 57 + 0.00000 0.00000 0.00000 + 3 37 99 101 + 7 213 281 66 30 349 23 385 + + 14.03639 -27.87660 + 3 28 55 54 + 0.00000 -0.00000 0.00000 + 2 53 289 + 5 175 237 228 352 308 + + 13.00544 -26.19457 + 4 29 28 54 53 + 0.00000 0.00000 0.00000 + 2 53 124 + 6 175 237 389 205 352 228 + + 19.25112 -27.17228 + 4 61 60 57 56 + 0.00000 0.00000 0.00000 + 2 37 262 + 6 213 308 281 30 349 363 + + 15.77497 -29.20840 + 6 61 56 55 28 455 454 + 0.00000 0.00000 0.00000 + 4 17 262 289 370 + 10 175 237 228 308 213 30 363 89 131 393 + + 19.88925 -29.76693 + 4 62 61 454 51 + 0.00000 0.00000 0.00000 + 2 84 370 + 6 131 454 30 363 408 89 + + -18.07057 -25.01632 + 4 36 35 30 457 + 0.00000 0.00000 0.00000 + 2 24 109 + 6 86 358 53 136 15 391 + + -15.63832 -23.81687 + 3 7 37 36 + -0.00000 -0.00000 -0.00000 + 2 41 410 + 5 130 345 15 136 165 + + -19.97147 -24.29512 + 4 40 30 35 34 + 0.00000 0.00000 0.00000 + 3 109 178 198 + 7 86 358 53 165 136 119 231 + + -10.87738 -27.16195 + 4 33 32 44 43 + 0.00000 0.00000 0.00000 + 2 3 351 + 6 101 319 391 354 442 52 + + -10.65024 -25.49465 + 3 43 8 33 + -0.00000 -0.00000 0.00000 + 3 301 351 378 + 6 153 345 101 391 354 442 + + -12.21545 -24.74879 + 3 7 33 8 + -0.00000 -0.00000 -0.00000 + 2 169 301 + 5 130 345 153 101 391 + + -21.75494 -27.72016 + 5 73 77 31 30 79 + 0.00000 0.00000 0.00000 + 2 158 407 + 7 86 358 319 191 267 236 444 + + -14.79445 -25.00107 + 4 36 457 33 7 + 0.00000 0.00000 0.00000 + 3 24 169 410 + 7 130 345 101 391 15 136 86 + + -25.19669 -24.36435 + 4 82 78 80 83 + 0.00000 0.00000 0.00000 + 1 375 + 5 325 401 444 239 13 + + -23.60014 -24.76622 + 4 80 79 39 83 + 0.00000 0.00000 0.00000 + 3 216 331 375 + 7 119 440 267 444 401 13 239 + + -20.21442 -21.45048 + 4 436 41 40 437 + 0.00000 0.00000 0.00000 + 2 197 320 + 6 119 231 270 8 85 252 + + -23.34829 -21.42997 + 4 83 39 38 458 + 0.00000 0.00000 0.00000 + 2 216 319 + 6 270 440 119 13 239 40 + + -19.63540 -19.75040 + 4 436 431 421 41 + 0.00000 0.00000 0.00000 + 4 57 186 197 346 + 8 231 270 186 192 177 198 8 85 + + -24.64411 -9.05173 + 4 81 84 141 148 + 0.00000 0.00000 0.00000 + 2 128 384 + 6 92 395 40 222 451 323 + + -22.55190 -9.43234 + 4 141 84 85 142 + 0.00000 0.00000 0.00000 + 3 46 129 384 + 7 40 92 45 280 222 451 20 + + -21.71054 -25.08519 + 4 40 39 79 30 + 0.00000 0.00000 0.00000 + 3 158 178 331 + 7 86 358 119 440 231 267 444 + + -17.78355 -18.38154 + 4 426 425 423 422 + 0.00000 0.00000 0.00000 + 2 162 338 + 6 192 400 379 2 171 0 + + -15.16803 -18.11416 + 5 87 424 427 6 102 + 0.00000 0.00000 0.00000 + 4 149 218 281 324 + 9 130 227 258 382 164 338 2 77 0 + + -14.70267 -15.02217 + 4 88 87 102 101 + 0.00000 0.00000 0.00000 + 2 218 313 + 6 258 382 341 164 249 338 + + -16.12649 -17.76687 + 4 425 424 87 459 + 0.00000 0.00000 0.00000 + 2 141 324 + 6 258 382 2 77 171 369 + + -19.93689 -18.47263 + 3 420 41 421 + -0.00000 -0.00000 0.00000 + 2 57 292 + 5 231 270 186 379 192 + + -21.65688 -18.19494 + 3 41 86 38 + -0.00000 -0.00000 0.00000 + 2 4 210 + 5 270 440 231 280 369 + + -20.60331 -18.06297 + 3 86 41 420 + -0.00000 -0.00000 -0.00000 + 3 6 210 292 + 6 231 270 280 369 186 379 + + -18.54721 -17.86541 + 5 425 459 86 420 423 + 0.00000 0.00000 0.00000 + 3 6 141 338 + 8 280 369 186 379 400 2 171 258 + + -22.72276 -15.51208 + 5 84 458 38 86 85 + 0.00000 0.00000 0.00000 + 3 4 129 319 + 8 270 440 40 92 45 280 369 13 + + 12.13535 -17.14101 + 5 25 24 70 69 127 + 0.00000 0.00000 0.00000 + 3 364 369 376 + 8 69 95 251 244 459 211 127 256 + + 10.17030 -13.04376 + 3 416 127 409 + 0.00000 -0.00000 0.00000 + 3 119 188 374 + 6 127 256 181 210 355 377 + + 10.11717 -12.40698 + 3 410 409 127 + 0.00000 -0.00000 0.00000 + 2 35 188 + 5 127 256 181 210 373 + + 9.15881 -11.44985 + 4 402 411 410 403 + 0.00000 0.00000 0.00000 + 2 332 358 + 6 122 197 196 181 373 184 + + 8.91908 -9.69404 + 4 401 400 124 123 + 0.00000 0.00000 0.00000 + 2 414 416 + 6 277 469 174 196 287 197 + + 10.17101 -11.78446 + 3 127 403 410 + 0.00000 -0.00000 0.00000 + 3 35 332 382 + 6 127 256 122 196 181 373 + + 10.64156 -11.25226 + 4 400 403 127 460 + 0.00000 0.00000 0.00000 + 2 44 382 + 6 127 256 196 287 122 265 + + 10.22130 -14.11145 + 4 127 416 419 25 + 0.00000 0.00000 0.00000 + 3 344 364 374 + 7 95 251 127 256 355 377 313 + + 10.65786 -8.53903 + 4 400 460 126 124 + 0.00000 0.00000 0.00000 + 3 44 108 414 + 7 174 469 68 265 196 287 256 + + 10.26737 -6.05361 + 3 120 124 126 + 0.00000 -0.00000 0.00000 + 2 108 227 + 5 174 294 469 68 265 + + 13.99085 -3.65932 + 5 166 163 126 125 167 + 0.00000 0.00000 0.00000 + 3 92 223 286 + 8 68 110 265 158 219 303 430 276 + + 16.97969 -12.92516 + 4 128 127 69 68 + 0.00000 0.00000 0.00000 + 2 105 376 + 6 244 261 459 127 256 403 + + -19.18220 2.15489 + 4 194 193 136 135 + 0.00000 0.00000 0.00000 + 2 51 238 + 6 340 388 447 109 362 107 + + -15.88402 3.20700 + 4 195 194 135 197 + 0.00000 0.00000 0.00000 + 3 34 51 257 + 7 340 388 107 362 242 218 376 + + -14.82631 -3.94310 + 3 146 145 144 + -0.00000 -0.00000 0.00000 + 1 98 + 4 88 194 72 388 + + -11.03422 -1.94344 + 4 151 135 146 152 + 0.00000 0.00000 0.00000 + 2 45 102 + 6 340 388 72 84 291 117 + + -11.37346 1.95258 + 4 198 197 135 151 + 0.00000 0.00000 0.00000 + 3 34 45 264 + 7 340 388 84 291 218 376 33 + + -11.52274 -5.44743 + 4 152 146 130 134 + 0.00000 0.00000 0.00000 + 3 102 138 387 + 7 302 317 47 72 388 84 117 + + -13.37254 -4.75259 + 3 146 144 130 + -0.00000 0.00000 0.00000 + 3 98 138 195 + 6 302 317 88 194 72 388 + + -7.52548 -6.82613 + 4 388 153 152 389 + 0.00000 0.00000 0.00000 + 2 40 168 + 6 84 117 70 102 396 71 + + -7.98159 2.11554 + 4 151 154 201 198 + 0.00000 0.00000 0.00000 + 3 31 264 360 + 7 84 291 70 33 376 39 351 + + -9.26534 -7.53398 + 5 389 152 134 133 390 + 0.00000 0.00000 0.00000 + 3 29 40 387 + 8 47 299 317 84 117 71 102 357 + + -6.25326 -7.21280 + 5 153 388 391 383 373 + 0.00000 0.00000 0.00000 + 4 11 151 168 408 + 9 70 117 145 342 150 468 102 396 357 + + 1.89261 33.37887 + 4 262 290 461 462 + 0.00000 0.00000 0.00000 + 3 81 275 361 + 7 206 425 63 384 312 415 62 + + -14.65406 33.35191 + 4 262 462 464 463 + 0.00000 0.00000 0.00000 + 1 275 + 5 206 425 62 312 106 + + 20.29439 32.98481 + 4 315 1 465 310 + 0.00000 0.00000 0.00000 + 2 373 395 + 6 104 125 336 394 266 415 + + 10.71221 33.38771 + 4 293 465 461 290 + 0.00000 0.00000 0.00000 + 2 272 361 + 6 63 384 394 312 415 104 + + 14.28097 21.15292 + 4 307 298 297 347 + 0.00000 0.00000 0.00000 + 3 284 302 406 + 7 79 250 402 142 190 99 409 + + 14.51917 23.60442 + 3 307 306 298 + 0.00000 0.00000 -0.00000 + 2 96 284 + 5 79 402 190 215 142 + + 15.43015 20.20687 + 3 346 307 347 + 0.00000 0.00000 0.00000 + 2 307 406 + 5 142 190 99 356 409 + + 22.97627 23.40918 + 5 313 312 309 308 303 + 0.00000 0.00000 0.00000 + 3 251 310 385 + 8 152 387 91 176 215 129 416 97 + + -2.65387 -30.01133 + 4 95 98 97 96 + 0.00000 0.00000 0.00000 + 2 14 234 + 6 156 353 51 247 298 257 + + -2.88295 -28.13763 + 5 47 93 96 97 19 + 0.00000 0.00000 0.00000 + 4 8 156 205 234 + 9 296 316 329 417 51 332 156 247 298 + + -2.65176 -25.97589 + 4 48 47 19 18 + 0.00000 0.00000 0.00000 + 2 63 156 + 6 316 398 296 329 417 370 + + 5.04827 -30.43849 + 4 92 91 50 27 + 0.00000 0.00000 0.00000 + 3 61 230 266 + 7 237 434 255 393 82 243 406 + + 8.62686 -30.11016 + 4 50 455 28 27 + 0.00000 0.00000 0.00000 + 2 17 230 + 6 237 434 175 255 393 89 + + -1.23377 -27.41005 + 4 97 99 456 19 + 0.00000 0.00000 0.00000 + 2 16 205 + 6 296 316 247 298 114 334 + + 5.12198 -26.22497 + 4 26 21 20 27 + 0.00000 0.00000 0.00000 + 2 69 70 + 6 135 334 398 389 434 237 + + 0.82636 -28.07242 + 5 20 456 99 467 100 + 0.00000 0.00000 0.00000 + 2 16 337 + 7 135 334 114 298 154 202 296 + + 3.21656 -29.08895 + 5 468 92 27 20 100 + 0.00000 0.00000 0.00000 + 3 69 266 337 + 8 135 334 237 434 243 406 154 202 + + 18.04356 18.02027 + 3 335 334 326 + 0.00000 0.00000 -0.00000 + 2 184 219 + 5 43 108 87 157 18 + + 18.42967 17.93368 + 4 335 326 325 340 + 0.00000 0.00000 0.00000 + 3 184 322 397 + 7 43 397 108 18 157 245 464 + + 16.61302 19.39556 + 4 333 332 346 345 + 0.00000 0.00000 0.00000 + 2 55 226 + 6 18 288 87 65 356 99 + + 18.18276 19.26325 + 4 343 332 335 340 + 0.00000 0.00000 0.00000 + 2 263 322 + 6 18 288 157 245 464 233 + + 19.39063 16.36990 + 3 325 324 218 + 0.00000 0.00000 0.00000 + 2 59 182 + 5 200 217 397 411 43 + + 19.17410 16.00174 + 4 324 327 225 218 + 0.00000 0.00000 0.00000 + 3 59 121 245 + 7 200 217 7 441 397 411 108 + + 19.81731 13.42439 + 4 224 219 218 225 + 0.00000 0.00000 0.00000 + 2 121 400 + 6 200 217 160 134 441 7 + + 20.52040 18.23224 + 5 469 300 341 340 218 + 0.00000 0.00000 0.00000 + 2 39 391 + 7 200 217 64 152 245 464 284 + + 19.39063 17.38263 + 3 340 325 218 + 0.00000 0.00000 0.00000 + 3 39 182 397 + 6 200 217 43 397 245 464 + + 17.74701 20.42844 + 4 342 341 466 307 + 0.00000 0.00000 0.00000 + 2 183 256 + 6 142 190 284 464 233 176 + + 17.06630 19.87766 + 5 342 307 346 332 343 + 0.00000 0.00000 0.00000 + 4 183 226 263 307 + 9 142 190 18 288 233 284 245 99 356 + + 22.89161 20.38886 + 3 303 308 300 + 0.00000 0.00000 0.00000 + 2 251 339 + 5 64 152 387 91 176 + + 20.51581 20.48655 + 4 466 341 300 308 + 0.00000 0.00000 0.00000 + 3 256 339 391 + 7 64 152 91 176 284 464 142 diff --git a/examples/core/tradeshow/tradeshowB.xml b/examples/core/tradeshow/tradeshowB.xml new file mode 100644 index 00000000..ad29e047 --- /dev/null +++ b/examples/core/tradeshow/tradeshowB.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/core/tradeshow/tradeshowS.xml b/examples/core/tradeshow/tradeshowS.xml new file mode 100644 index 00000000..39430861 --- /dev/null +++ b/examples/core/tradeshow/tradeshowS.xml @@ -0,0 +1,1744 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/core/tradeshow/tradeshowV.xml b/examples/core/tradeshow/tradeshowV.xml new file mode 100644 index 00000000..6e4f01aa --- /dev/null +++ b/examples/core/tradeshow/tradeshowV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/mengeLogo.png b/examples/mengeLogo.png new file mode 100644 index 00000000..7d3b2221 Binary files /dev/null and b/examples/mengeLogo.png differ diff --git a/examples/plugin/aircraft/aircraft.nav b/examples/plugin/aircraft/aircraft.nav new file mode 100644 index 00000000..dabaa017 --- /dev/null +++ b/examples/plugin/aircraft/aircraft.nav @@ -0,0 +1,1662 @@ +296 + 24.58720 0.22860 + 24.25700 0.22860 + 24.25700 -0.22860 + 24.58720 -0.22860 + 25.04440 0.22860 + 25.04440 -0.22860 + 25.37460 0.22860 + 25.37460 -0.22860 + 25.83180 0.22860 + 25.83180 -0.22860 + 26.16200 0.22860 + 26.16200 -0.22860 + 26.61920 0.22860 + 26.61920 -0.22860 + 26.94940 0.22860 + 26.94940 -0.22860 + 27.40660 0.22860 + 27.40660 -0.22860 + 27.73680 0.22860 + 27.73680 -0.22860 + 28.19400 0.22860 + 28.19400 -0.22860 + 28.52420 0.22860 + 28.52420 -0.22860 + 28.98140 0.22860 + 28.98140 -0.22860 + 29.31160 0.22860 + 29.31160 -0.22860 + 29.76880 0.22860 + 29.76880 -0.22860 + 30.09900 0.22860 + 30.09900 -0.22860 + 30.55620 0.22860 + 30.55620 -0.22860 + 30.88640 0.22860 + 30.88640 -0.22860 + 31.34360 0.22860 + 31.34360 -0.22860 + 31.67380 0.22860 + 31.67380 -0.22860 + 32.13100 0.22860 + 32.13100 -0.22860 + 32.46120 0.22860 + 32.46120 -0.22860 + 32.91839 0.22860 + 32.91839 -0.22860 + 33.24860 0.22860 + 33.24860 -0.22860 + 33.68040 0.43180 + 33.68040 -0.43180 + 33.68040 0.50800 + 33.24860 0.50800 + 34.49320 0.27940 + 34.49320 -0.27940 + 8.38200 0.25400 + 8.28324 1.57791 + 7.62966 1.46579 + 7.49300 0.32385 + 7.49300 1.44270 + 8.38200 1.58775 + 9.90600 0.31750 + 9.90600 1.72245 + 9.27100 1.68032 + 9.27100 0.25400 + 25.04440 1.76022 + 24.58720 1.76022 + 25.83180 1.76022 + 25.37460 1.76022 + 26.61920 1.76022 + 26.16200 1.76022 + 27.40660 1.76022 + 26.94940 1.76022 + 28.19400 1.76022 + 27.73680 1.76022 + 28.98140 1.76022 + 28.52420 1.76022 + 29.76880 1.76022 + 29.31160 1.76022 + 30.55620 1.76022 + 30.09900 1.76022 + 31.34360 1.76022 + 30.88640 1.76022 + 32.13100 1.76022 + 31.67380 1.76022 + 32.91839 1.73848 + 32.46120 1.74588 + 24.25700 1.76022 + 23.79980 1.76022 + 23.79980 0.22860 + 23.46960 0.22860 + 23.46960 1.76022 + 23.01240 1.76022 + 23.01240 0.22860 + 22.68220 0.22860 + 22.68220 1.76022 + 22.22500 1.76022 + 22.22500 0.22860 + 21.89480 0.22860 + 21.89480 1.25095 + 21.43760 1.25095 + 21.43760 0.22860 + 21.10740 0.22860 + 21.10740 1.25095 + 20.65020 1.25095 + 20.65020 0.22860 + 20.32000 0.22860 + 20.32000 1.76022 + 19.53260 1.76022 + 19.53260 0.22860 + 19.20240 0.22860 + 19.20240 1.76022 + 18.71980 1.76022 + 18.71980 0.22860 + 18.38960 0.22860 + 18.38960 1.76022 + 17.90700 1.76022 + 17.90700 0.22860 + 17.57680 0.22860 + 17.57680 1.76022 + 17.09420 1.76022 + 17.09420 0.22860 + 16.76400 0.22860 + 16.76400 1.76022 + 16.28140 1.76022 + 16.28140 0.22860 + 15.95120 0.22860 + 15.95120 1.76022 + 15.46860 1.76022 + 15.46860 0.22860 + 15.13840 0.22860 + 15.13840 1.76022 + 14.65580 1.76022 + 14.65580 0.22860 + 14.32560 0.22860 + 14.32560 1.76022 + 13.51280 1.76022 + 13.51280 0.53340 + 12.87780 0.31750 + 12.87780 1.76022 + 12.39520 1.76022 + 12.39520 0.31750 + 11.98880 0.31750 + 11.98880 1.76022 + 11.50620 1.76022 + 11.50620 0.31750 + 11.09980 0.31750 + 11.09980 1.75449 + 10.61720 1.75062 + 10.61720 0.31750 + 34.49320 0.43180 + 34.51860 0.27940 + 34.51860 -0.27940 + 34.64560 0.30480 + 34.64560 -0.30480 + 35.48380 -0.30480 + 35.48380 0.30480 + 35.48380 0.82550 + 34.64560 1.06045 + 35.46744 1.47817 + 34.81845 1.56334 + 34.51860 1.60178 + 34.51860 1.06045 + 35.63620 0.82550 + 35.63620 1.45340 + 21.89480 1.76022 + 21.43760 1.76022 + 21.10740 1.76022 + 20.65020 1.76022 + 33.24860 -0.50800 + 33.68040 -0.50800 + 23.79980 -0.22860 + 23.46960 -0.22860 + 23.01240 -0.22860 + 22.68220 -0.22860 + 22.22500 -0.22860 + 21.89480 -0.22860 + 21.43760 -0.22860 + 21.10740 -0.22860 + 20.65020 -0.22860 + 20.32000 -0.22860 + 19.53260 -0.22860 + 19.20240 -0.22860 + 18.71980 -0.22860 + 18.38960 -0.22860 + 17.90700 -0.22860 + 17.57680 -0.22860 + 17.09420 -0.22860 + 16.76400 -0.22860 + 16.28140 -0.22860 + 15.95120 -0.22860 + 15.46860 -0.22860 + 15.13840 -0.22860 + 14.65580 -0.22860 + 14.32560 -0.22860 + 13.51280 -0.53340 + 13.28420 0.31750 + 13.28420 -0.31750 + 12.87780 -0.31750 + 12.39520 -0.31750 + 11.98880 -0.31750 + 11.50620 -0.31750 + 11.09980 -0.31750 + 10.61720 -0.31750 + 9.90600 -0.31750 + 9.27100 -0.42545 + 8.71220 -0.42545 + 7.84860 -0.27940 + 7.12470 0.32385 + 7.12470 -0.27940 + 7.84860 -1.03505 + 8.71220 -1.28270 + 8.00089 -1.53500 + 8.67964 -1.62825 + 7.71206 -1.04790 + 7.72160 -1.48360 + 8.86460 -1.64752 + 8.86460 -1.28270 + 9.27100 -1.68032 + 9.90600 -1.72245 + 24.58720 -1.76022 + 25.04440 -1.76022 + 25.37460 -1.76022 + 25.83180 -1.76022 + 26.16200 -1.76022 + 26.61920 -1.76022 + 26.94940 -1.76022 + 27.40660 -1.76022 + 27.73680 -1.76022 + 28.19400 -1.76022 + 28.52420 -1.76022 + 28.98140 -1.76022 + 29.31160 -1.76022 + 29.76880 -1.76022 + 30.09900 -1.76022 + 30.55620 -1.76022 + 30.88640 -1.76022 + 31.34360 -1.76022 + 31.67380 -1.76022 + 32.13100 -1.76022 + 32.46120 -1.74588 + 32.91839 -1.73848 + 23.79980 -1.76022 + 24.25700 -1.76022 + 23.01240 -1.76022 + 23.46960 -1.76022 + 22.22500 -1.76022 + 22.68220 -1.76022 + 21.43760 -1.25095 + 21.89480 -1.25095 + 20.65020 -1.25095 + 21.10740 -1.25095 + 19.53260 -1.76022 + 20.32000 -1.76022 + 18.71980 -1.76022 + 19.20240 -1.76022 + 17.90700 -1.76022 + 18.38960 -1.76022 + 17.09420 -1.76022 + 17.57680 -1.76022 + 16.28140 -1.76022 + 16.76400 -1.76022 + 15.46860 -1.76022 + 15.95120 -1.76022 + 14.65580 -1.76022 + 15.13840 -1.76022 + 13.51280 -1.76022 + 14.32560 -1.76022 + 12.39520 -1.76022 + 12.87780 -1.76022 + 11.50620 -1.76022 + 11.98880 -1.76022 + 10.61720 -1.75062 + 11.09980 -1.75449 + 34.49320 -0.43180 + 34.64560 -1.06045 + 35.48380 -0.82550 + 34.81845 -1.56334 + 35.46744 -1.47817 + 34.51860 -1.06045 + 34.51860 -1.60178 + 35.63620 -1.45340 + 35.63620 -0.82550 + 6.47517 -2.07003 + 9.45581 -2.07004 + 0.00000 -7.00000 + 10.00000 -7.00000 + 21.43760 -1.76022 + 21.89480 -1.76022 + 20.65020 -1.76022 + 21.10740 -1.76022 + 43.00000 -7.00000 + 36.25242 -2.07004 + 43.00000 7.00000 + 36.13591 2.14983 + 0.00000 7.00000 + 7.06711 2.07810 +154 + 136 194 93 94 + 18 19 8 9 + 117 185 84 85 + 38 40 19 39 + 247 248 125 145 + 156 157 61 62 + 4 5 1 2 + 274 275 139 140 + 148 202 100 101 + 47 49 23 68 + 20 21 9 10 + 129 191 90 91 + 201 202 100 137 + 205 206 104 106 + 93 96 43 73 + 44 45 21 22 + 31 33 15 118 + 36 37 17 18 + 120 186 85 86 + 121 187 86 87 + 152 155 60 61 + 153 154 60 139 + 89 92 42 71 + 54 205 103 104 + 195 196 94 95 + 137 140 54 96 + 63 204 102 103 + 10 12 5 32 + 48 52 25 57 + 92 172 71 72 + 133 193 92 93 + 7 9 3 112 + 140 198 96 97 + 185 186 85 130 + 102 166 66 67 + 189 190 89 132 + 96 174 73 74 + 26 28 13 36 + 52 53 25 58 + 292 293 149 150 + 18 20 9 34 + 23 25 11 116 + 183 184 83 129 + 125 189 88 89 + 173 174 73 124 + 181 182 81 128 + 30 31 14 15 + 22 23 10 11 + 8 9 3 4 + 39 41 19 120 + 12 13 5 6 + 104 178 77 78 + 105 179 78 79 + 32 33 15 16 + 88 170 69 70 + 38 39 18 19 + 24 25 11 12 + 28 29 13 14 + 16 17 7 8 + 275 277 140 142 + 211 212 107 143 + 42 44 21 40 + 209 211 107 108 + 101 177 76 77 + 108 180 79 80 + 247 286 145 147 + 98 99 44 65 + 121 124 50 87 + 283 285 144 148 + 145 201 99 100 + 56 57 26 27 + 112 182 81 82 + 113 183 82 83 + 128 190 89 90 + 113 116 48 83 + 203 204 102 110 + 132 192 91 92 + 282 283 143 144 + 105 108 46 79 + 54 55 26 28 + 40 41 19 20 + 34 35 16 17 + 133 136 53 93 + 49 53 25 138 + 0 4 1 30 + 60 203 101 102 + 282 284 144 151 + 101 104 45 77 + 43 45 21 121 + 150 151 58 59 + 193 194 93 134 + 156 158 62 64 + 157 159 62 63 + 141 144 55 98 + 177 178 77 126 + 6 7 2 3 + 3 5 1 111 + 1 88 41 69 + 145 148 56 100 + 97 175 74 75 + 19 21 9 115 + 129 132 52 91 + 179 180 79 127 + 14 16 7 33 + 274 276 140 141 + 141 199 97 98 + 97 100 44 75 + 125 128 51 89 + 35 37 17 119 + 249 250 126 146 + 116 184 83 84 + 191 192 91 133 + 100 176 75 76 + 109 181 80 81 + 54 57 26 104 + 89 171 70 71 + 102 103 45 66 + 250 289 146 147 + 144 200 98 99 + 60 63 29 102 + 42 43 20 21 + 46 48 23 24 + 34 36 17 38 + 14 15 6 7 + 99 165 65 67 + 48 49 23 25 + 294 295 150 151 + 30 32 15 37 + 197 198 96 135 + 290 291 148 149 + 199 200 98 136 + 187 188 87 131 + 117 120 49 85 + 46 47 22 23 + 109 112 47 81 + 93 173 72 73 + 137 197 95 96 + 175 176 75 125 + 210 212 107 109 + 11 13 5 113 + 171 172 71 123 + 6 8 3 31 + 10 11 4 5 + 0 3 0 1 + 27 29 13 117 + 1 2 0 69 + 2 170 69 122 + 57 206 104 105 + 22 24 11 35 + 15 17 7 114 + 209 210 106 107 + 26 27 12 13 + 124 188 87 88 + 152 153 59 60 +296 + 186 257 130 127 + 125 126 51 192 + 86 87 41 61 + 113 114 48 83 + 164 165 65 93 + 31 233 118 191 + 15 225 114 139 + 249 288 146 65 + 285 290 148 102 + 211 282 143 261 + 56 58 27 173 + 105 106 46 262 + 142 143 55 37 + 107 108 46 207 + 72 73 34 199 + 109 110 47 49 + 268 197 135 248 + 67 6 31 170 + 271 272 137 238 + 48 50 24 33 + 206 209 106 256 + 243 244 123 55 + 60 61 29 179 + 199 198 97 40 + 42 40 20 232 + 36 80 38 227 + 41 43 20 96 + 103 104 45 203 + 144 145 99 48 + 46 44 22 258 + 255 256 129 276 + 45 47 22 60 + 218 203 110 146 + 50 51 24 51 + 79 30 37 279 + 139 140 54 280 + 224 13 113 271 + 143 144 55 28 + 53 151 58 119 + 74 75 35 72 + 198 267 135 216 + 175 174 74 240 + 238 41 120 26 + 49 273 138 109 + 215 216 109 165 + 153 274 139 178 + 170 241 122 182 + 90 91 42 212 + 145 146 56 71 + 110 111 47 249 + 138 139 54 35 + 51 46 24 29 + 293 291 149 62 + 129 130 52 294 + 281 275 142 242 + 244 171 123 222 + 152 150 59 272 + 232 29 117 282 + 68 69 32 77 + 226 17 114 286 + 47 168 68 224 + 87 88 41 220 + 291 283 148 70 + 97 98 44 69 + 154 155 60 231 + 288 289 146 183 + 240 45 121 31 + 148 60 101 22 + 251 252 127 180 + 98 164 65 4 + 283 212 143 195 + 146 147 56 251 + 75 22 35 188 + 127 128 51 115 + 184 255 129 30 + 96 97 74 63 + 185 184 84 74 + 69 10 32 266 + 122 123 50 295 + 55 56 26 10 + 71 14 33 269 + 83 38 39 206 + 176 247 125 245 + 114 115 48 234 + 20 72 34 14 + 157 152 61 56 + 194 265 134 289 + 231 232 117 57 + 39 237 120 196 + 263 264 133 135 + 27 231 117 87 + 173 172 72 209 + 95 96 43 75 + 165 166 67 169 + 189 188 88 197 + 234 33 118 134 + 43 239 121 237 + 219 220 111 246 + 81 34 38 133 + 178 249 126 7 + 260 187 131 205 + 287 248 145 193 + 290 292 149 217 + 262 189 132 94 + 8 66 31 167 + 82 83 39 81 + 214 211 108 9 + 57 207 105 158 + 258 185 130 76 + 273 53 138 38 + 1 86 41 2 + 193 192 92 166 + 2 3 0 159 + 7 221 112 288 + 119 120 49 185 + 128 129 90 53 + 191 190 90 168 + 245 246 124 164 + 269 270 136 221 + 151 153 59 45 + 135 136 53 162 + 16 70 33 128 + 133 134 53 150 + 195 137 95 214 + 230 25 116 275 + 35 235 119 229 + 19 227 115 291 + 257 258 130 108 + 70 71 33 80 + 116 117 84 236 + 259 260 131 100 + 12 68 32 58 + 99 100 44 144 + 34 32 16 171 + 33 35 16 125 + 264 191 133 116 + 101 102 45 175 + 62 63 29 263 + 28 76 36 151 + 225 226 114 59 + 279 276 141 293 + 208 206 105 20 + 163 158 64 181 + 196 194 94 86 + 100 101 76 136 + 295 293 150 52 + 203 202 101 253 + 77 26 36 274 + 223 224 113 36 + 160 161 63 290 + 134 135 53 120 + 76 77 36 147 + 149 48 57 19 + 23 229 116 257 + 201 200 99 287 + 11 223 113 148 + 250 177 126 218 + 162 163 64 142 + 207 208 105 141 + 3 219 111 97 + 277 280 142 255 + 254 181 128 233 + 136 195 94 123 + 54 59 28 176 + 246 173 124 91 + 216 210 109 239 + 192 263 133 89 + 66 67 31 17 + 190 261 132 186 + 166 167 66 260 + 6 4 2 252 + 32 78 37 292 + 5 7 2 113 + 58 57 27 107 + 84 85 40 198 + 102 99 67 132 + 59 55 28 79 + 24 74 35 39 + 274 278 141 204 + 61 62 29 137 + 252 179 127 215 + 158 159 62 277 + 241 242 122 265 + 289 286 147 241 + 169 49 68 43 + 120 121 86 278 + 261 262 132 103 + 222 9 112 267 + 22 20 10 84 + 132 133 92 122 + 21 23 10 153 + 233 234 118 95 + 126 127 51 73 + 248 175 125 41 + 112 113 82 3 + 212 215 109 44 + 237 238 120 42 + 188 259 131 130 + 85 42 40 24 + 73 18 34 285 + 266 193 134 111 + 180 251 127 68 + 118 119 49 114 + 104 105 78 11 + 278 279 141 140 + 187 186 86 0 + 38 36 18 25 + 108 109 80 15 + 37 39 18 88 + 172 243 123 21 + 89 90 42 47 + 228 21 115 190 + 91 92 42 223 + 93 94 43 225 + 137 138 54 50 + 179 178 78 99 + 267 268 135 16 + 292 294 150 247 + 177 176 76 82 + 141 142 55 12 + 88 89 70 210 + 270 199 136 23 + 171 170 70 46 + 92 93 72 213 + 168 169 68 184 + 94 95 43 92 + 182 253 128 230 + 80 81 38 98 + 205 204 103 250 + 235 236 119 281 + 253 254 128 161 + 155 156 61 244 + 40 82 39 105 + 181 180 80 201 + 115 116 48 129 + 0 1 0 110 + 117 118 49 202 + 239 240 121 66 + 272 201 137 154 + 210 205 106 228 + 174 245 124 117 + 286 287 145 101 + 275 154 139 64 + 131 132 52 189 + 156 162 64 157 + 247 250 147 156 + 220 5 111 172 + 294 284 151 273 + 197 196 95 143 + 111 112 47 194 + 204 217 110 283 + 147 148 56 67 + 4 64 30 268 + 202 271 137 18 + 213 214 108 106 + 280 281 142 54 + 209 213 108 254 + 229 230 116 124 + 44 84 40 174 + 183 182 82 226 + 167 103 66 27 + 282 295 151 145 + 106 107 46 13 + 63 54 103 163 + 65 0 30 235 + 242 2 122 112 + 10 8 4 104 + 9 11 4 155 + 64 65 30 264 + 14 12 6 131 + 52 149 57 152 + 13 15 6 6 + 150 52 58 270 + 284 285 144 8 + 26 24 12 177 + 25 27 12 90 + 256 183 129 259 + 159 160 63 149 + 121 122 50 78 + 30 28 14 138 + 140 141 97 219 + 236 37 119 208 + 29 31 14 5 + 217 218 110 32 + 124 125 88 1 + 18 16 8 121 + 17 19 8 126 + 200 269 136 118 + 221 222 112 187 + 265 266 134 200 + 161 157 63 85 + 227 228 115 211 + 78 79 37 34 + 276 277 140 160 + 130 131 52 243 + 123 124 50 284 +defaultGrp +152 + 24.42210 0.00000 + 4 0 1 2 3 + 0.00000 0.00000 0.00000 + 2 143 145 + 6 235 264 110 112 265 159 + + 24.81580 0.00000 + 4 4 0 3 5 + 0.00000 0.00000 0.00000 + 4 6 84 96 143 + 8 235 264 112 159 170 252 172 246 + + 25.20950 0.00000 + 4 6 4 5 7 + 0.00000 0.00000 0.00000 + 2 6 95 + 6 170 252 172 246 17 113 + + 25.60320 0.00000 + 4 8 6 7 9 + 0.00000 0.00000 0.00000 + 4 31 48 95 141 + 8 17 170 113 172 104 266 187 267 + + 25.99690 0.00000 + 4 10 8 9 11 + 0.00000 0.00000 0.00000 + 2 48 142 + 6 104 266 187 267 77 155 + + 26.39060 0.00000 + 4 12 10 11 13 + 0.00000 0.00000 0.00000 + 4 27 50 139 142 + 8 77 266 155 267 131 269 36 271 + + 26.78430 0.00000 + 4 14 12 13 15 + 0.00000 0.00000 0.00000 + 2 50 123 + 6 131 269 36 271 80 6 + + 27.17800 0.00000 + 4 16 14 15 17 + 0.00000 0.00000 0.00000 + 4 58 103 123 149 + 8 80 269 6 271 121 285 59 286 + + 27.57170 0.00000 + 4 18 16 17 19 + 0.00000 0.00000 0.00000 + 2 1 58 + 6 121 285 59 286 199 126 + + 27.96540 0.00000 + 4 20 18 19 21 + 0.00000 0.00000 0.00000 + 4 1 10 40 100 + 8 199 285 126 286 84 188 190 211 + + 28.35910 0.00000 + 4 22 20 21 23 + 0.00000 0.00000 0.00000 + 2 10 47 + 6 84 188 190 211 72 153 + + 28.75280 0.00000 + 4 24 22 23 25 + 0.00000 0.00000 0.00000 + 4 41 47 56 148 + 8 72 188 153 190 177 274 124 275 + + 29.14650 0.00000 + 4 26 24 25 27 + 0.00000 0.00000 0.00000 + 2 56 151 + 6 177 274 124 275 147 90 + + 29.54020 0.00000 + 4 28 26 27 29 + 0.00000 0.00000 0.00000 + 4 37 57 144 151 + 8 147 274 90 275 138 279 57 282 + + 29.93390 0.00000 + 4 30 28 29 31 + 0.00000 0.00000 0.00000 + 2 46 57 + 6 138 279 57 282 34 5 + + 30.32760 0.00000 + 4 32 30 31 33 + 0.00000 0.00000 0.00000 + 4 16 46 53 127 + 8 34 279 5 282 133 171 95 134 + + 30.72130 0.00000 + 4 34 32 33 35 + 0.00000 0.00000 0.00000 + 2 53 81 + 6 133 171 95 134 98 125 + + 31.11500 0.00000 + 4 36 34 35 37 + 0.00000 0.00000 0.00000 + 4 17 81 108 122 + 8 98 133 125 134 25 206 208 281 + + 31.50870 0.00000 + 4 38 36 37 39 + 0.00000 0.00000 0.00000 + 2 17 55 + 6 25 206 208 281 81 88 + + 31.90240 0.00000 + 4 40 38 39 41 + 0.00000 0.00000 0.00000 + 4 3 49 55 80 + 8 81 206 88 208 24 232 26 42 + + 32.29610 0.00000 + 4 42 40 41 43 + 0.00000 0.00000 0.00000 + 2 80 120 + 6 24 232 26 42 198 96 + + 32.68979 0.00000 + 4 44 42 43 45 + 0.00000 0.00000 0.00000 + 4 15 61 88 120 + 8 24 198 26 96 29 258 31 66 + + 33.08349 0.00000 + 4 46 44 45 47 + 0.00000 0.00000 0.00000 + 2 15 133 + 6 29 258 31 66 51 60 + + 33.46450 -0.00000 + 4 48 46 47 49 + 0.00000 0.00000 0.00000 + 4 9 121 125 133 + 8 29 51 31 60 19 152 43 184 + + 33.46450 0.41910 + 4 48 50 51 46 + 0.00000 0.00000 0.00000 + 1 121 + 5 29 51 19 152 33 + + 34.08680 0.00000 + 4 52 48 49 53 + 0.00000 0.00000 0.00000 + 4 28 38 83 125 + 8 19 152 43 184 270 272 38 109 + + 7.94698 0.90539 + 4 54 55 56 57 + 0.00000 0.00000 0.00000 + 3 70 79 114 + 7 163 263 79 176 10 107 173 + + 7.53855 1.07745 + 3 56 58 57 + 0.00000 -0.00000 0.00000 + 1 70 + 4 10 79 107 173 + + 8.34908 1.13989 + 3 54 59 55 + 0.00000 0.00000 0.00000 + 1 79 + 4 163 263 79 176 + + 9.58850 0.99357 + 4 60 61 62 63 + 0.00000 0.00000 0.00000 + 1 119 + 5 22 67 179 137 263 + + 24.81580 0.99441 + 4 4 64 65 0 + 0.00000 0.00000 0.00000 + 1 84 + 5 235 264 170 252 268 + + 25.60320 0.99441 + 4 8 66 67 6 + 0.00000 0.00000 0.00000 + 1 141 + 5 17 170 104 266 167 + + 26.39060 0.99441 + 4 12 68 69 10 + 0.00000 0.00000 0.00000 + 1 27 + 5 77 266 131 269 58 + + 27.17800 0.99441 + 4 16 70 71 14 + 0.00000 0.00000 0.00000 + 1 103 + 5 80 269 121 285 128 + + 27.96540 0.99441 + 4 20 72 73 18 + 0.00000 0.00000 0.00000 + 1 40 + 5 199 285 84 188 14 + + 28.75280 0.99441 + 4 24 74 75 22 + 0.00000 0.00000 0.00000 + 1 148 + 5 72 188 177 274 39 + + 29.54020 0.99441 + 4 28 76 77 26 + 0.00000 0.00000 0.00000 + 1 37 + 5 147 274 138 279 151 + + 30.32760 0.99441 + 4 32 78 79 30 + 0.00000 0.00000 0.00000 + 1 127 + 5 34 279 133 171 292 + + 31.11500 0.99441 + 4 36 80 81 34 + 0.00000 0.00000 0.00000 + 1 122 + 5 98 133 25 206 227 + + 31.90240 0.99441 + 4 40 82 83 38 + 0.00000 0.00000 0.00000 + 1 3 + 5 81 206 24 232 105 + + 32.68979 0.98539 + 4 44 84 85 42 + 0.00000 0.00000 0.00000 + 1 61 + 5 24 198 29 258 174 + + 24.02840 0.99441 + 4 1 86 87 88 + 0.00000 0.00000 0.00000 + 1 97 + 5 110 235 2 61 220 + + 23.24100 0.99441 + 4 89 90 91 92 + 0.00000 0.00000 0.00000 + 1 22 + 5 210 220 47 212 223 + + 22.45360 0.99441 + 4 93 94 95 96 + 0.00000 0.00000 0.00000 + 1 14 + 5 213 223 225 92 75 + + 21.66620 0.73978 + 4 97 98 99 100 + 0.00000 0.00000 0.00000 + 2 66 106 + 6 63 75 69 132 175 144 + + 20.87880 0.73978 + 4 101 102 103 104 + 0.00000 0.00000 0.00000 + 2 87 116 + 6 136 144 175 27 260 203 + + 19.92630 0.99441 + 4 105 106 107 108 + 0.00000 0.00000 0.00000 + 1 78 + 5 11 203 262 13 207 + + 18.96110 0.99441 + 4 109 110 111 112 + 0.00000 0.00000 0.00000 + 1 134 + 5 15 207 49 249 194 + + 18.14830 0.99441 + 4 113 114 115 116 + 0.00000 0.00000 0.00000 + 1 74 + 5 3 194 83 234 129 + + 17.33550 0.99441 + 4 117 118 119 120 + 0.00000 0.00000 0.00000 + 1 132 + 5 129 236 202 114 185 + + 16.52270 0.99441 + 4 121 122 123 124 + 0.00000 0.00000 0.00000 + 1 67 + 5 185 278 78 295 284 + + 15.70990 0.99441 + 4 125 126 127 128 + 0.00000 0.00000 0.00000 + 1 107 + 5 1 284 192 73 115 + + 14.89710 0.99441 + 4 129 130 131 132 + 0.00000 0.00000 0.00000 + 1 101 + 5 53 115 294 243 189 + + 13.91920 1.07061 + 4 133 134 135 136 + 0.00000 0.00000 0.00000 + 1 82 + 5 122 189 150 120 162 + + 12.63650 1.03886 + 4 137 138 139 140 + 0.00000 0.00000 0.00000 + 1 25 + 5 123 214 50 35 280 + + 11.74750 1.03886 + 4 141 142 143 144 + 0.00000 0.00000 0.00000 + 1 93 + 5 219 280 12 37 28 + + 10.85850 1.03503 + 4 145 146 147 148 + 0.00000 0.00000 0.00000 + 1 98 + 5 28 48 71 251 67 + + 34.22227 0.38100 + 3 52 149 48 + 0.00000 0.00000 -0.00000 + 1 28 + 4 19 152 270 272 + + 34.50590 0.00000 + 4 150 52 53 151 + 0.00000 0.00000 0.00000 + 2 38 89 + 6 270 272 38 109 56 119 + + 34.58210 0.00000 + 4 152 150 151 153 + 0.00000 0.00000 0.00000 + 2 89 153 + 6 56 272 38 119 85 45 + + 35.06470 0.00000 + 4 154 155 152 153 + 0.00000 0.00000 0.00000 + 3 20 21 153 + 7 56 85 45 119 64 242 231 + + 35.06470 0.62389 + 4 155 156 157 152 + 0.00000 0.00000 0.00000 + 2 5 20 + 6 56 85 64 231 244 290 + + 35.10382 1.23186 + 4 156 158 159 157 + 0.00000 0.00000 0.00000 + 3 5 91 92 + 7 231 244 85 290 142 181 277 + + 34.62531 1.32151 + 4 159 160 161 157 + 0.00000 0.00000 0.00000 + 1 92 + 5 85 290 181 277 149 + + 35.55591 1.14564 + 4 156 162 163 158 + 0.00000 0.00000 0.00000 + 1 91 + 5 231 244 142 181 157 + + 21.66620 1.50559 + 4 98 164 165 99 + 0.00000 0.00000 0.00000 + 2 66 124 + 6 63 69 132 175 4 93 + + 20.87880 1.50559 + 4 102 166 167 103 + 0.00000 0.00000 0.00000 + 2 34 116 + 6 136 175 27 260 93 169 + + 21.27250 1.50559 + 4 102 99 165 166 + 0.00000 0.00000 0.00000 + 2 34 124 + 6 132 175 136 4 93 169 + + 33.46450 -0.41910 + 4 49 47 168 169 + 0.00000 0.00000 0.00000 + 1 9 + 5 31 60 43 184 224 + + 24.02840 0.00000 + 4 88 170 2 1 + 0.00000 0.00000 0.00000 + 4 54 97 145 146 + 8 110 235 112 265 61 220 46 222 + + 23.63470 0.00000 + 4 88 89 171 170 + 0.00000 0.00000 0.00000 + 2 54 115 + 6 61 220 210 46 222 55 + + 23.24100 0.00000 + 4 92 172 171 89 + 0.00000 0.00000 0.00000 + 4 22 29 115 140 + 8 210 220 212 223 55 222 91 209 + + 22.84730 0.00000 + 4 92 93 173 172 + 0.00000 0.00000 0.00000 + 2 29 135 + 6 212 223 213 91 209 164 + + 22.45360 0.00000 + 4 96 174 173 93 + 0.00000 0.00000 0.00000 + 4 14 36 44 135 + 8 213 223 75 92 91 164 41 240 + + 22.05990 0.00000 + 4 96 97 175 174 + 0.00000 0.00000 0.00000 + 2 36 99 + 6 75 92 63 41 240 193 + + 21.66620 0.00000 + 4 100 176 175 97 + 0.00000 0.00000 0.00000 + 4 99 106 112 137 + 8 63 75 132 144 41 193 82 218 + + 21.27250 0.00000 + 4 100 101 177 176 + 0.00000 0.00000 0.00000 + 2 63 112 + 6 132 144 136 82 218 156 + + 20.87880 0.00000 + 4 104 178 177 101 + 0.00000 0.00000 0.00000 + 4 51 63 87 94 + 8 136 144 27 203 156 218 99 215 + + 20.48510 0.00000 + 4 104 105 179 178 + 0.00000 0.00000 0.00000 + 2 51 52 + 6 27 203 11 99 215 180 + + 19.92630 0.00000 + 4 108 180 179 105 + 0.00000 0.00000 0.00000 + 4 52 64 78 102 + 8 11 203 13 207 180 215 201 233 + + 19.36750 0.00000 + 4 108 109 181 180 + 0.00000 0.00000 0.00000 + 2 64 113 + 6 13 207 15 201 233 161 + + 18.96110 0.00000 + 4 112 182 181 109 + 0.00000 0.00000 0.00000 + 4 45 71 113 134 + 8 15 207 194 249 161 233 226 259 + + 18.55470 0.00000 + 4 112 113 183 182 + 0.00000 0.00000 0.00000 + 2 71 72 + 6 194 249 3 226 259 276 + + 18.14830 0.00000 + 4 116 184 183 113 + 0.00000 0.00000 0.00000 + 4 42 72 74 110 + 8 3 194 129 234 259 276 74 76 + + 17.74190 0.00000 + 4 116 117 185 184 + 0.00000 0.00000 0.00000 + 2 2 110 + 6 129 234 236 74 76 108 + + 17.33550 0.00000 + 4 120 186 185 117 + 0.00000 0.00000 0.00000 + 4 2 18 33 132 + 8 129 236 114 185 76 108 0 205 + + 16.92910 0.00000 + 4 120 121 187 186 + 0.00000 0.00000 0.00000 + 2 18 19 + 6 114 185 278 0 205 100 + + 16.52270 0.00000 + 4 124 188 187 121 + 0.00000 0.00000 0.00000 + 4 19 67 131 152 + 8 185 278 284 295 100 205 94 197 + + 16.11630 0.00000 + 4 124 125 189 188 + 0.00000 0.00000 0.00000 + 2 43 152 + 6 284 295 1 94 197 103 + + 15.70990 0.00000 + 4 128 190 189 125 + 0.00000 0.00000 0.00000 + 4 35 43 73 107 + 8 1 284 73 115 94 103 116 168 + + 15.30350 0.00000 + 4 128 129 191 190 + 0.00000 0.00000 0.00000 + 2 11 73 + 6 73 115 53 116 168 135 + + 14.89710 0.00000 + 4 132 192 191 129 + 0.00000 0.00000 0.00000 + 4 11 76 101 111 + 8 53 115 189 243 116 135 111 166 + + 14.49070 0.00000 + 4 132 133 193 192 + 0.00000 0.00000 0.00000 + 2 30 76 + 6 189 243 122 111 166 200 + + 13.91920 0.00000 + 4 136 194 193 133 + 0.00000 0.00000 0.00000 + 4 0 30 82 90 + 8 122 189 120 162 111 200 86 143 + + 13.39850 0.00000 + 4 195 196 194 136 + 0.00000 0.00000 0.00000 + 2 0 24 + 6 120 162 86 143 123 248 + + 13.08100 0.00000 + 4 195 137 197 196 + 0.00000 0.00000 0.00000 + 2 24 136 + 6 123 214 162 143 248 16 + + 12.63650 0.00000 + 4 140 198 197 137 + 0.00000 0.00000 0.00000 + 4 25 32 128 136 + 8 123 214 35 280 16 248 23 40 + + 12.19200 0.00000 + 4 140 141 199 198 + 0.00000 0.00000 0.00000 + 2 32 105 + 6 35 280 219 23 40 221 + + 11.74750 0.00000 + 4 144 200 199 141 + 0.00000 0.00000 0.00000 + 4 93 105 118 130 + 8 219 280 28 37 23 221 154 287 + + 11.30300 0.00000 + 4 144 145 201 200 + 0.00000 0.00000 0.00000 + 2 69 118 + 6 28 37 48 154 287 238 + + 10.85850 0.00000 + 4 148 202 201 145 + 0.00000 0.00000 0.00000 + 4 8 12 69 98 + 8 28 48 67 251 154 238 146 253 + + 10.26160 0.00000 + 4 148 60 203 202 + 0.00000 0.00000 0.00000 + 2 8 85 + 6 22 67 251 146 253 32 + + 9.58850 -0.04286 + 4 63 204 203 60 + 0.00000 0.00000 0.00000 + 4 26 75 85 119 + 8 22 67 137 263 32 146 228 250 + + 8.90905 -0.08572 + 4 54 205 204 63 + 0.00000 0.00000 0.00000 + 2 23 26 + 6 163 263 137 228 250 239 + + 8.10895 -0.03175 + 4 57 206 205 54 + 0.00000 0.00000 0.00000 + 4 13 23 114 147 + 8 163 263 107 173 228 239 20 141 + + 7.39775 0.02223 + 4 207 208 206 57 + 0.00000 0.00000 0.00000 + 1 147 + 5 107 173 20 141 158 + + 8.28040 -0.75565 + 4 205 206 209 210 + 0.00000 0.00000 0.00000 + 2 13 150 + 6 228 239 20 141 256 165 + + 8.31033 -1.37025 + 4 210 209 211 212 + 0.00000 0.00000 0.00000 + 4 60 62 138 150 + 8 20 256 165 239 9 106 70 195 + + 7.82079 -1.27539 + 4 211 209 213 214 + 0.00000 0.00000 0.00000 + 1 62 + 5 20 256 9 106 254 + + 8.78026 -1.46029 + 4 210 212 215 216 + 0.00000 0.00000 0.00000 + 1 138 + 5 165 239 70 195 44 + + 9.58850 -1.03643 + 4 203 204 217 218 + 0.00000 0.00000 0.00000 + 1 75 + 5 32 146 228 250 283 + + 24.81580 -0.99441 + 4 5 3 219 220 + 0.00000 0.00000 0.00000 + 1 96 + 5 112 159 172 246 97 + + 25.60320 -0.99441 + 4 9 7 221 222 + 0.00000 0.00000 0.00000 + 1 31 + 5 113 172 187 267 288 + + 26.39060 -0.99441 + 4 13 11 223 224 + 0.00000 0.00000 0.00000 + 1 139 + 5 155 267 36 271 148 + + 27.17800 -0.99441 + 4 17 15 225 226 + 0.00000 0.00000 0.00000 + 1 149 + 5 6 271 59 286 139 + + 27.96540 -0.99441 + 4 21 19 227 228 + 0.00000 0.00000 0.00000 + 1 100 + 5 126 286 190 211 291 + + 28.75280 -0.99441 + 4 25 23 229 230 + 0.00000 0.00000 0.00000 + 1 41 + 5 153 190 124 275 257 + + 29.54020 -0.99441 + 4 29 27 231 232 + 0.00000 0.00000 0.00000 + 1 144 + 5 90 275 57 282 87 + + 30.32760 -0.99441 + 4 33 31 233 234 + 0.00000 0.00000 0.00000 + 1 16 + 5 5 282 95 134 191 + + 31.11500 -0.99441 + 4 37 35 235 236 + 0.00000 0.00000 0.00000 + 1 108 + 5 125 134 208 281 229 + + 31.90240 -0.99441 + 4 41 39 237 238 + 0.00000 0.00000 0.00000 + 1 49 + 5 88 208 26 42 196 + + 32.68979 -0.98539 + 4 45 43 239 240 + 0.00000 0.00000 0.00000 + 1 88 + 5 26 96 31 66 237 + + 24.02840 -0.99441 + 4 2 170 241 242 + 0.00000 0.00000 0.00000 + 1 146 + 5 112 265 46 222 182 + + 23.24100 -0.99441 + 4 171 172 243 244 + 0.00000 0.00000 0.00000 + 1 140 + 5 55 222 91 209 21 + + 22.45360 -0.99441 + 4 173 174 245 246 + 0.00000 0.00000 0.00000 + 1 44 + 5 91 164 41 240 117 + + 21.66620 -0.73978 + 4 175 176 247 248 + 0.00000 0.00000 0.00000 + 2 4 137 + 6 41 193 82 218 245 101 + + 20.87880 -0.73978 + 4 177 178 249 250 + 0.00000 0.00000 0.00000 + 2 94 109 + 6 156 218 99 215 7 245 + + 19.92630 -0.99441 + 4 179 180 251 252 + 0.00000 0.00000 0.00000 + 1 102 + 5 180 215 201 233 68 + + 18.96110 -0.99441 + 4 181 182 253 254 + 0.00000 0.00000 0.00000 + 1 45 + 5 161 233 226 259 230 + + 18.14830 -0.99441 + 4 183 184 255 256 + 0.00000 0.00000 0.00000 + 1 42 + 5 259 276 74 76 30 + + 17.33550 -0.99441 + 4 185 186 257 258 + 0.00000 0.00000 0.00000 + 1 33 + 5 76 108 0 205 127 + + 16.52270 -0.99441 + 4 187 188 259 260 + 0.00000 0.00000 0.00000 + 1 131 + 5 100 205 94 197 130 + + 15.70990 -0.99441 + 4 189 190 261 262 + 0.00000 0.00000 0.00000 + 1 35 + 5 94 103 116 168 186 + + 14.89710 -0.99441 + 4 191 192 263 264 + 0.00000 0.00000 0.00000 + 1 111 + 5 116 135 111 166 89 + + 13.91920 -1.07061 + 4 193 194 265 266 + 0.00000 0.00000 0.00000 + 1 90 + 5 111 200 86 143 289 + + 12.63650 -1.03886 + 4 197 198 267 268 + 0.00000 0.00000 0.00000 + 1 128 + 5 16 248 23 40 216 + + 11.74750 -1.03886 + 4 199 200 269 270 + 0.00000 0.00000 0.00000 + 1 130 + 5 23 221 154 287 118 + + 10.85850 -1.03503 + 4 201 202 271 272 + 0.00000 0.00000 0.00000 + 1 12 + 5 154 238 146 253 18 + + 34.22227 -0.38100 + 3 53 49 273 + 0.00000 -0.00000 -0.00000 + 1 83 + 4 43 184 38 109 + + 35.06470 -0.62389 + 4 154 153 274 275 + 0.00000 0.00000 0.00000 + 2 7 21 + 6 45 119 64 242 178 54 + + 35.10382 -1.23186 + 4 275 274 276 277 + 0.00000 0.00000 0.00000 + 3 7 59 104 + 7 45 178 54 242 140 293 160 + + 34.62531 -1.32151 + 4 276 274 278 279 + 0.00000 0.00000 0.00000 + 1 104 + 5 45 178 140 293 204 + + 35.55591 -1.14564 + 4 275 277 280 281 + 0.00000 0.00000 0.00000 + 1 59 + 5 54 242 160 293 255 + + 8.15288 -1.82583 + 4 212 211 282 283 + 0.00000 0.00000 0.00000 + 2 60 77 + 6 9 106 70 195 261 62 + + 6.48274 -4.53502 + 4 283 282 284 285 + 0.00000 0.00000 0.00000 + 3 68 77 86 + 7 9 261 62 70 247 273 8 + + 21.66620 -1.50559 + 4 248 247 286 287 + 0.00000 0.00000 0.00000 + 2 4 65 + 6 82 245 101 193 183 241 + + 20.87880 -1.50559 + 4 250 249 288 289 + 0.00000 0.00000 0.00000 + 2 109 117 + 6 7 99 156 245 65 183 + + 21.27250 -1.50559 + 4 250 289 286 247 + 0.00000 0.00000 0.00000 + 2 65 117 + 6 82 245 156 183 241 65 + + 24.67706 -4.53502 + 4 283 285 290 291 + 0.00000 0.00000 0.00000 + 2 68 129 + 6 62 70 8 273 102 52 + + 39.59708 0.01995 + 4 291 290 292 293 + 0.00000 0.00000 0.00000 + 2 39 129 + 6 8 102 52 62 217 145 + + 21.55075 4.55698 + 4 293 292 294 295 + 0.00000 0.00000 0.00000 + 2 39 126 + 6 102 217 52 145 247 261 + + 3.38557 0.00202 + 4 295 294 284 282 + 0.00000 0.00000 0.00000 + 2 86 126 + 6 9 261 247 273 217 145 diff --git a/examples/plugin/aircraft/aircraftV.xml b/examples/plugin/aircraft/aircraftV.xml new file mode 100644 index 00000000..9755a0a3 --- /dev/null +++ b/examples/plugin/aircraft/aircraftV.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/plugin/aircraft/load/loadBack.xml b/examples/plugin/aircraft/load/loadBack.xml new file mode 100644 index 00000000..ea6ac3db --- /dev/null +++ b/examples/plugin/aircraft/load/loadBack.xml @@ -0,0 +1,11 @@ + + + diff --git a/examples/plugin/aircraft/load/loadBack/loadBackB.xml b/examples/plugin/aircraft/load/loadBack/loadBackB.xml new file mode 100644 index 00000000..ef002d75 --- /dev/null +++ b/examples/plugin/aircraft/load/loadBack/loadBackB.xml @@ -0,0 +1,111 @@ + + + + + // Entrance to the plane + + + + + // coach class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // First class + + + + + + + + + + + // Coach entering and getting seat assigned + + + + + + + + + + + + // First class entering plane and getting seat assigned + + + + + + + + + + + + // Passenger sitting in aisle seat + + + // Transitions + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/load/loadByZone.xml b/examples/plugin/aircraft/load/loadByZone.xml new file mode 100644 index 00000000..b8583e3c --- /dev/null +++ b/examples/plugin/aircraft/load/loadByZone.xml @@ -0,0 +1,11 @@ + + + diff --git a/examples/plugin/aircraft/load/loadByZone/loadZoneB.xml b/examples/plugin/aircraft/load/loadByZone/loadZoneB.xml new file mode 100644 index 00000000..312a302e --- /dev/null +++ b/examples/plugin/aircraft/load/loadByZone/loadZoneB.xml @@ -0,0 +1,196 @@ + + + + + // Entrance to the plane + + + + + // coach class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // First class + + + + + + + + + + + // coach class zone 1 + // Move to plane entry + // Get a goal and move to it + + + + + + + + + + + + + + + + + + + + + + + // coach class zone 2 + // Move to plane entry + // Get a goal and move to it + + + + + + + + + + + + + + + + + + + + + // coach class zone 3 + // Move to plane entry + // Get a goal and move to it + + + + + + + + + + + + + + + + + + + + + // coach class zone 4 + // Move to plane entry + // Get a goal and move to it + + + + + + + + + + + + + + + + + + + + + // first class + // Move to plane entry + // Get a goal and move to it + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/load/loadByZone/loadZoneS.xml b/examples/plugin/aircraft/load/loadByZone/loadZoneS.xml new file mode 100644 index 00000000..19d08806 --- /dev/null +++ b/examples/plugin/aircraft/load/loadByZone/loadZoneS.xml @@ -0,0 +1,474 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/load/loadFront.xml b/examples/plugin/aircraft/load/loadFront.xml new file mode 100644 index 00000000..5f87b8bf --- /dev/null +++ b/examples/plugin/aircraft/load/loadFront.xml @@ -0,0 +1,11 @@ + + + diff --git a/examples/plugin/aircraft/load/loadFront/loadFrontB.xml b/examples/plugin/aircraft/load/loadFront/loadFrontB.xml new file mode 100644 index 00000000..a24f1814 --- /dev/null +++ b/examples/plugin/aircraft/load/loadFront/loadFrontB.xml @@ -0,0 +1,111 @@ + + + + + // Entrance to the plane + + + + + // coach class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // First class + + + + + + + + + + + // Coach entering and getting seat assigned + + + + + + + + + + + + // First class entering plane and getting seat assigned + + + + + + + + + + + + // Passenger sitting in aisle seat + + + // Transitions + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/load/loadRandom.xml b/examples/plugin/aircraft/load/loadRandom.xml new file mode 100644 index 00000000..0eec1f07 --- /dev/null +++ b/examples/plugin/aircraft/load/loadRandom.xml @@ -0,0 +1,11 @@ + + + diff --git a/examples/plugin/aircraft/load/loadRandom/loadRandomB.xml b/examples/plugin/aircraft/load/loadRandom/loadRandomB.xml new file mode 100644 index 00000000..708301cf --- /dev/null +++ b/examples/plugin/aircraft/load/loadRandom/loadRandomB.xml @@ -0,0 +1,111 @@ + + + + + // Entrance to the plane + + + + + // coach class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // First class + + + + + + + + + + + // Coach entering and getting seat assigned + + + + + + + + + + + + // First class entering plane and getting seat assigned + + + + + + + + + + + + // Passenger sitting in aisle seat + + + // Transitions + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/load/loadS.xml b/examples/plugin/aircraft/load/loadS.xml new file mode 100644 index 00000000..de7162f1 --- /dev/null +++ b/examples/plugin/aircraft/load/loadS.xml @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/unload/simpleUnload.xml b/examples/plugin/aircraft/unload/simpleUnload.xml new file mode 100644 index 00000000..85290911 --- /dev/null +++ b/examples/plugin/aircraft/unload/simpleUnload.xml @@ -0,0 +1,14 @@ + + + + view="../../airlineV.xml" + diff --git a/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadB.xml b/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadB.xml new file mode 100644 index 00000000..b4589c48 --- /dev/null +++ b/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadB.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadS.xml b/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadS.xml new file mode 100644 index 00000000..6fdc3775 --- /dev/null +++ b/examples/plugin/aircraft/unload/simpleUnload/simpleUnloadS.xml @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/unload/unloadAircraftV.xml b/examples/plugin/aircraft/unload/unloadAircraftV.xml new file mode 100644 index 00000000..9f11ce91 --- /dev/null +++ b/examples/plugin/aircraft/unload/unloadAircraftV.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/examples/plugin/aircraft/unload/waitingAgent.xml b/examples/plugin/aircraft/unload/waitingAgent.xml new file mode 100644 index 00000000..2386d073 --- /dev/null +++ b/examples/plugin/aircraft/unload/waitingAgent.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/aircraft/unload/waitingAgent/waitingAgentB.xml b/examples/plugin/aircraft/unload/waitingAgent/waitingAgentB.xml new file mode 100644 index 00000000..90d49eac --- /dev/null +++ b/examples/plugin/aircraft/unload/waitingAgent/waitingAgentB.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/aircraft/unload/waitingAgent/waitingAgentS.xml b/examples/plugin/aircraft/unload/waitingAgent/waitingAgentS.xml new file mode 100644 index 00000000..2ff16dab --- /dev/null +++ b/examples/plugin/aircraft/unload/waitingAgent/waitingAgentS.xml @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + waiting top + + + + + waiting bottom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/denseFormation.xml b/examples/plugin/denseFormation.xml new file mode 100644 index 00000000..284c1f71 --- /dev/null +++ b/examples/plugin/denseFormation.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/denseFormation/DenseSquare.txt b/examples/plugin/denseFormation/DenseSquare.txt new file mode 100644 index 00000000..99b67302 --- /dev/null +++ b/examples/plugin/denseFormation/DenseSquare.txt @@ -0,0 +1,42 @@ +16 +-3 -3 1 +-1 -3 1 +-0 -3 1 +1 -3 1 +3 -3 1 +-3 -1 1 +-3 0 1 +-3 1 1 +-3 3 1 +-1 3 1 +0 3 1 +1 3 1 +3 3 1 +3 1 1 +3 0 1 +3 -1 1 +-2 -2 0 +-2 -1 0 +-2 0 0 +-2 1 0 +-2 2 0 +-1 -2 0 +-1 -1 0 +-1 0 0 +-1 1 0 +-1 2 0 +0 -2 0 +0 -1 0 +0 0 0 +0 1 0 +0 2 0 +1 -2 0 +1 -1 0 +1 0 0 +1 1 0 +1 2 0 +2 -2 0 +2 -1 0 +2 0 0 +2 1 0 +2 2 0 \ No newline at end of file diff --git a/examples/plugin/denseFormation/denseFormationB.xml b/examples/plugin/denseFormation/denseFormationB.xml new file mode 100644 index 00000000..e301f35a --- /dev/null +++ b/examples/plugin/denseFormation/denseFormationB.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/plugin/denseFormation/denseFormationS.xml b/examples/plugin/denseFormation/denseFormationS.xml new file mode 100644 index 00000000..3717c808 --- /dev/null +++ b/examples/plugin/denseFormation/denseFormationS.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/denseFormation/denseFormationV.xml b/examples/plugin/denseFormation/denseFormationV.xml new file mode 100644 index 00000000..9c6fdd06 --- /dev/null +++ b/examples/plugin/denseFormation/denseFormationV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/plugin/formation.xml b/examples/plugin/formation.xml new file mode 100644 index 00000000..0a045a6f --- /dev/null +++ b/examples/plugin/formation.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/formation/formationB.xml b/examples/plugin/formation/formationB.xml new file mode 100644 index 00000000..23745661 --- /dev/null +++ b/examples/plugin/formation/formationB.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formation/formationS.xml b/examples/plugin/formation/formationS.xml new file mode 100644 index 00000000..ef95aa4e --- /dev/null +++ b/examples/plugin/formation/formationS.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formation/formationV.xml b/examples/plugin/formation/formationV.xml new file mode 100644 index 00000000..8f3ef56c --- /dev/null +++ b/examples/plugin/formation/formationV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/plugin/formation/squareForm.txt b/examples/plugin/formation/squareForm.txt new file mode 100644 index 00000000..31d0d404 --- /dev/null +++ b/examples/plugin/formation/squareForm.txt @@ -0,0 +1,6 @@ +4 +-2 2 1 +2 2 1 +-2 -2 1 +2 -2 1 +0 0 0 diff --git a/examples/plugin/formationChange.xml b/examples/plugin/formationChange.xml new file mode 100644 index 00000000..1962bc67 --- /dev/null +++ b/examples/plugin/formationChange.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/formationChange/formationChangeB.xml b/examples/plugin/formationChange/formationChangeB.xml new file mode 100644 index 00000000..7f855baa --- /dev/null +++ b/examples/plugin/formationChange/formationChangeB.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formationChange/formationChangeS.xml b/examples/plugin/formationChange/formationChangeS.xml new file mode 100644 index 00000000..ae5ce328 --- /dev/null +++ b/examples/plugin/formationChange/formationChangeS.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formationChange/formationChangeV.xml b/examples/plugin/formationChange/formationChangeV.xml new file mode 100644 index 00000000..14dd520d --- /dev/null +++ b/examples/plugin/formationChange/formationChangeV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/plugin/formationChange/lineForm.txt b/examples/plugin/formationChange/lineForm.txt new file mode 100644 index 00000000..d3bbcc38 --- /dev/null +++ b/examples/plugin/formationChange/lineForm.txt @@ -0,0 +1,7 @@ +5 +0 -4 1 +0 -2 1 +0 0 1 +0 2 1 +0 4 1 + diff --git a/examples/plugin/formationChange/squareForm.txt b/examples/plugin/formationChange/squareForm.txt new file mode 100644 index 00000000..31d0d404 --- /dev/null +++ b/examples/plugin/formationChange/squareForm.txt @@ -0,0 +1,6 @@ +4 +-2 2 1 +2 2 1 +-2 -2 1 +2 -2 1 +0 0 0 diff --git a/examples/plugin/formationChange/wedgeForm.txt b/examples/plugin/formationChange/wedgeForm.txt new file mode 100644 index 00000000..e79fd437 --- /dev/null +++ b/examples/plugin/formationChange/wedgeForm.txt @@ -0,0 +1,6 @@ +5 +-1 -1 1 +1 -1 1 +0 .8 1 +-.7 .5 1 +.7 .5 1 diff --git a/examples/plugin/formationNavigation.xml b/examples/plugin/formationNavigation.xml new file mode 100644 index 00000000..d7567a31 --- /dev/null +++ b/examples/plugin/formationNavigation.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/formationNavigation/bigSquare.txt b/examples/plugin/formationNavigation/bigSquare.txt new file mode 100644 index 00000000..92e7d142 --- /dev/null +++ b/examples/plugin/formationNavigation/bigSquare.txt @@ -0,0 +1,26 @@ +16 +-2 -2 1 +-1 -2 1 +0 -2 1 +1 -2 1 +2 -2 1 +-2 2 1 +-1 2 1 +0 2 1 +1 2 1 +2 2 1 +-2 -1 1 +-2 0 1 +-2 1 1 +2 -1 1 +2 0 1 +2 1 1 +-1 -1 0 +0 -1 0 +1 -1 0 +-1 0 0 +0 0 0 +1 0 0 +-1 1 0 +0 1 0 +1 1 0 diff --git a/examples/plugin/formationNavigation/formationNavigationB.xml b/examples/plugin/formationNavigation/formationNavigationB.xml new file mode 100644 index 00000000..200e8a39 --- /dev/null +++ b/examples/plugin/formationNavigation/formationNavigationB.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formationNavigation/formationNavigationS.xml b/examples/plugin/formationNavigation/formationNavigationS.xml new file mode 100644 index 00000000..4feab4a8 --- /dev/null +++ b/examples/plugin/formationNavigation/formationNavigationS.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/formationNavigation/formationNavigationV.xml b/examples/plugin/formationNavigation/formationNavigationV.xml new file mode 100644 index 00000000..5e7e652e --- /dev/null +++ b/examples/plugin/formationNavigation/formationNavigationV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/plugin/formationNavigation/graph.txt b/examples/plugin/formationNavigation/graph.txt new file mode 100644 index 00000000..eb6a0fc2 --- /dev/null +++ b/examples/plugin/formationNavigation/graph.txt @@ -0,0 +1,10 @@ +4 +2 8.353541 6.136796 +1 7.982818 -1.547356 +2 -4.929274 6.123839 +1 -4.943811 0.028619 +3 +1 0 +3 2 +2 0 + diff --git a/examples/plugin/fundDiag.xml b/examples/plugin/fundDiag.xml new file mode 100644 index 00000000..d84cb8c2 --- /dev/null +++ b/examples/plugin/fundDiag.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/fundDiag/fundDiagB.xml b/examples/plugin/fundDiag/fundDiagB.xml new file mode 100644 index 00000000..3d042999 --- /dev/null +++ b/examples/plugin/fundDiag/fundDiagB.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/fundDiag/fundDiagS.xml b/examples/plugin/fundDiag/fundDiagS.xml new file mode 100644 index 00000000..da8cb2d0 --- /dev/null +++ b/examples/plugin/fundDiag/fundDiagS.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/fundDiag/fundDiagV.xml b/examples/plugin/fundDiag/fundDiagV.xml new file mode 100644 index 00000000..48edccf1 --- /dev/null +++ b/examples/plugin/fundDiag/fundDiagV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/plugin/propertyX.xml b/examples/plugin/propertyX.xml new file mode 100644 index 00000000..d2af2944 --- /dev/null +++ b/examples/plugin/propertyX.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/propertyX/propertyXB.xml b/examples/plugin/propertyX/propertyXB.xml new file mode 100644 index 00000000..d84ad7f1 --- /dev/null +++ b/examples/plugin/propertyX/propertyXB.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/propertyX/propertyXS.xml b/examples/plugin/propertyX/propertyXS.xml new file mode 100644 index 00000000..fc8ee9ed --- /dev/null +++ b/examples/plugin/propertyX/propertyXS.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/propertyX/propertyXV.xml b/examples/plugin/propertyX/propertyXV.xml new file mode 100644 index 00000000..57633737 --- /dev/null +++ b/examples/plugin/propertyX/propertyXV.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/plugin/terrain.xml b/examples/plugin/terrain.xml new file mode 100644 index 00000000..9fd66eaf --- /dev/null +++ b/examples/plugin/terrain.xml @@ -0,0 +1,9 @@ + + + diff --git a/examples/plugin/terrain/battlefield.ht b/examples/plugin/terrain/battlefield.ht new file mode 100644 index 00000000..6dff628e --- /dev/null +++ b/examples/plugin/terrain/battlefield.ht @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/examples/plugin/terrain/battlefield.png b/examples/plugin/terrain/battlefield.png new file mode 100644 index 00000000..70dadd0d Binary files /dev/null and b/examples/plugin/terrain/battlefield.png differ diff --git a/examples/plugin/terrain/terrainB.xml b/examples/plugin/terrain/terrainB.xml new file mode 100644 index 00000000..572cf3ad --- /dev/null +++ b/examples/plugin/terrain/terrainB.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/terrain/terrainS.xml b/examples/plugin/terrain/terrainS.xml new file mode 100644 index 00000000..514dae2a --- /dev/null +++ b/examples/plugin/terrain/terrainS.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/plugin/terrain/terrainV.xml b/examples/plugin/terrain/terrainV.xml new file mode 100644 index 00000000..a4e40d81 --- /dev/null +++ b/examples/plugin/terrain/terrainV.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/projects/VS2005/Menge/Menge05.ncb b/projects/VS2005/Menge/Menge05.ncb new file mode 100644 index 00000000..88afee0d Binary files /dev/null and b/projects/VS2005/Menge/Menge05.ncb differ diff --git a/projects/VS2005/Menge/Menge05.sln b/projects/VS2005/Menge/Menge05.sln new file mode 100644 index 00000000..2d6cf9c6 --- /dev/null +++ b/projects/VS2005/Menge/Menge05.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "menge", "menge.vcproj", "{B6CABAC3-735C-4046-97D5-DB2E9621F8C1}" + ProjectSection(ProjectDependencies) = postProject + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142} = {F5B90B6A-8E12-496E-99EB-3CE9CBB79142} + {C406DAEC-0886-4771-8DEA-9D7329B46CC1} = {C406DAEC-0886-4771-8DEA-9D7329B46CC1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "tinyxml_lib.vcproj", "{C406DAEC-0886-4771-8DEA-9D7329B46CC1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MengeCore", "MengeCore.vcproj", "{F5B90B6A-8E12-496E-99EB-3CE9CBB79142}" + ProjectSection(ProjectDependencies) = postProject + {C406DAEC-0886-4771-8DEA-9D7329B46CC1} = {C406DAEC-0886-4771-8DEA-9D7329B46CC1} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + ReleaseST|Win32 = ReleaseST|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Debug|Win32.Build.0 = Debug|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Release|Win32.ActiveCfg = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Release|Win32.Build.0 = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.ReleaseST|Win32.Build.0 = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.Build.0 = Debug|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.ActiveCfg = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.Build.0 = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.ReleaseST|Win32.Build.0 = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Debug|Win32.ActiveCfg = Debug|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Debug|Win32.Build.0 = Debug|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Release|Win32.ActiveCfg = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Release|Win32.Build.0 = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.ReleaseST|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/VS2005/Menge/MengeCore.vcproj b/projects/VS2005/Menge/MengeCore.vcproj new file mode 100644 index 00000000..d394263c --- /dev/null +++ b/projects/VS2005/Menge/MengeCore.vcproj @@ -0,0 +1,2094 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Menge/menge.vcproj b/projects/VS2005/Menge/menge.vcproj new file mode 100644 index 00000000..5c958003 --- /dev/null +++ b/projects/VS2005/Menge/menge.vcproj @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Menge/tinyxml_lib.vcproj b/projects/VS2005/Menge/tinyxml_lib.vcproj new file mode 100644 index 00000000..d9c8c46c --- /dev/null +++ b/projects/VS2005/Menge/tinyxml_lib.vcproj @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/AgtDummy.vcproj b/projects/VS2005/Plugins/AgtDummy.vcproj new file mode 100644 index 00000000..84ab7ca2 --- /dev/null +++ b/projects/VS2005/Plugins/AgtDummy.vcproj @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/AgtHelbing.vcproj b/projects/VS2005/Plugins/AgtHelbing.vcproj new file mode 100644 index 00000000..7218b8bd --- /dev/null +++ b/projects/VS2005/Plugins/AgtHelbing.vcproj @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/AgtJohansson.vcproj b/projects/VS2005/Plugins/AgtJohansson.vcproj new file mode 100644 index 00000000..124949a1 --- /dev/null +++ b/projects/VS2005/Plugins/AgtJohansson.vcproj @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/AgtKaramouzas.vcproj b/projects/VS2005/Plugins/AgtKaramouzas.vcproj new file mode 100644 index 00000000..5bf3a306 --- /dev/null +++ b/projects/VS2005/Plugins/AgtKaramouzas.vcproj @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/AgtZanlungo.vcproj b/projects/VS2005/Plugins/AgtZanlungo.vcproj new file mode 100644 index 00000000..25f8986a --- /dev/null +++ b/projects/VS2005/Plugins/AgtZanlungo.vcproj @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/Aircraft.vcproj b/projects/VS2005/Plugins/Aircraft.vcproj new file mode 100644 index 00000000..8e9094ff --- /dev/null +++ b/projects/VS2005/Plugins/Aircraft.vcproj @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/Formations.vcproj b/projects/VS2005/Plugins/Formations.vcproj new file mode 100644 index 00000000..3fe6ff11 --- /dev/null +++ b/projects/VS2005/Plugins/Formations.vcproj @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/FundDiag.vcproj b/projects/VS2005/Plugins/FundDiag.vcproj new file mode 100644 index 00000000..b60fb771 --- /dev/null +++ b/projects/VS2005/Plugins/FundDiag.vcproj @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/Plugins05.ncb b/projects/VS2005/Plugins/Plugins05.ncb new file mode 100644 index 00000000..b7d8bd72 Binary files /dev/null and b/projects/VS2005/Plugins/Plugins05.ncb differ diff --git a/projects/VS2005/Plugins/Plugins05.sln b/projects/VS2005/Plugins/Plugins05.sln new file mode 100644 index 00000000..c9644f46 --- /dev/null +++ b/projects/VS2005/Plugins/Plugins05.sln @@ -0,0 +1,86 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtKaramouzas", "AgtKaramouzas.vcproj", "{4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtDummy", "AgtDummy.vcproj", "{77BE22D2-25E3-4025-8512-9BB5015ED73F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtHelbing", "AgtHelbing.vcproj", "{2090832D-3620-4E86-904D-08632C3D1AA0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtJohansson", "AgtJohansson.vcproj", "{77491B89-9A8B-4E69-B19A-58AFED2A6E2F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtZanlungo", "AgtZanlungo.vcproj", "{5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Terrain", "Terrain.vcproj", "{C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Formations", "Formations.vcproj", "{B321C48F-6A77-4949-AEF3-F313A31D357F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FundDiag", "FundDiag.vcproj", "{2CB742B3-536D-4E39-BA12-6D029E8FCA2A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Aircraft", "Aircraft.vcproj", "{2B4A4D3D-27A9-4C27-95BE-21737C22EA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + ReleaseST|Win32 = ReleaseST|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Debug|Win32.Build.0 = Debug|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Release|Win32.ActiveCfg = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Release|Win32.Build.0 = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.ReleaseST|Win32.Build.0 = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Debug|Win32.ActiveCfg = Debug|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Debug|Win32.Build.0 = Debug|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Release|Win32.ActiveCfg = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Release|Win32.Build.0 = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.ReleaseST|Win32.Build.0 = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Debug|Win32.ActiveCfg = Debug|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Debug|Win32.Build.0 = Debug|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Release|Win32.ActiveCfg = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Release|Win32.Build.0 = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.ReleaseST|Win32.Build.0 = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Debug|Win32.ActiveCfg = Debug|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Debug|Win32.Build.0 = Debug|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Release|Win32.ActiveCfg = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Release|Win32.Build.0 = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.ReleaseST|Win32.Build.0 = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Debug|Win32.ActiveCfg = Debug|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Debug|Win32.Build.0 = Debug|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Release|Win32.ActiveCfg = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Release|Win32.Build.0 = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.ReleaseST|Win32.Build.0 = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Debug|Win32.Build.0 = Debug|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Release|Win32.ActiveCfg = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Release|Win32.Build.0 = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.ReleaseST|Win32.Build.0 = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Debug|Win32.ActiveCfg = Debug|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Debug|Win32.Build.0 = Debug|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Release|Win32.ActiveCfg = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Release|Win32.Build.0 = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.ReleaseST|Win32.Build.0 = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Debug|Win32.Build.0 = Debug|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Release|Win32.ActiveCfg = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Release|Win32.Build.0 = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.ReleaseST|Win32.Build.0 = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Debug|Win32.Build.0 = Debug|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Release|Win32.ActiveCfg = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Release|Win32.Build.0 = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.ReleaseST|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/VS2005/Plugins/SamplePlugin.vcproj b/projects/VS2005/Plugins/SamplePlugin.vcproj new file mode 100644 index 00000000..ca469827 --- /dev/null +++ b/projects/VS2005/Plugins/SamplePlugin.vcproj @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/Plugins/Terrain.vcproj b/projects/VS2005/Plugins/Terrain.vcproj new file mode 100644 index 00000000..8b1cf491 --- /dev/null +++ b/projects/VS2005/Plugins/Terrain.vcproj @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/VS2005/pluginMacros.vsprops b/projects/VS2005/pluginMacros.vsprops new file mode 100644 index 00000000..d34388a3 --- /dev/null +++ b/projects/VS2005/pluginMacros.vsprops @@ -0,0 +1,19 @@ + + + + + + diff --git a/projects/VS2005/userMacros.vsprops b/projects/VS2005/userMacros.vsprops new file mode 100644 index 00000000..9f29e9fc --- /dev/null +++ b/projects/VS2005/userMacros.vsprops @@ -0,0 +1,19 @@ + + + + + + diff --git a/projects/VS2012/Menge/Menge12.sln b/projects/VS2012/Menge/Menge12.sln new file mode 100644 index 00000000..2cb9f129 --- /dev/null +++ b/projects/VS2012/Menge/Menge12.sln @@ -0,0 +1,38 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "menge", "menge.vcxproj", "{B6CABAC3-735C-4046-97D5-DB2E9621F8C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "tinyxml_lib.vcxproj", "{C406DAEC-0886-4771-8DEA-9D7329B46CC1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MengeCore", "MengeCore.vcxproj", "{F5B90B6A-8E12-496E-99EB-3CE9CBB79142}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + ReleaseST|Win32 = ReleaseST|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Debug|Win32.Build.0 = Debug|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Release|Win32.ActiveCfg = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.Release|Win32.Build.0 = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1}.ReleaseST|Win32.Build.0 = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.Build.0 = Debug|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.ActiveCfg = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.Build.0 = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.ReleaseST|Win32.Build.0 = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Debug|Win32.ActiveCfg = Debug|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Debug|Win32.Build.0 = Debug|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Release|Win32.ActiveCfg = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.Release|Win32.Build.0 = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142}.ReleaseST|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/VS2012/Menge/MengeCore.vcxproj b/projects/VS2012/Menge/MengeCore.vcxproj new file mode 100644 index 00000000..4d3b1fc6 --- /dev/null +++ b/projects/VS2012/Menge/MengeCore.vcxproj @@ -0,0 +1,550 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {F5B90B6A-8E12-496E-99EB-3CE9CBB79142} + MengeCore + Win32Proj + + + + DynamicLibrary + v110 + MultiByte + true + + + DynamicLibrary + v110 + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(SrcDir)\include;$(SrcDir)\MengeCore;$(SrcDir)\MengeCore\Agents;$(SrcDir)\MengeCore\Runtime;$(SrcDir)\MengeCore\PluginEngine;$(SrcDir)\MengeCore\SceneGraph;$(SrcDir)\MengeCore\viewer;$(SrcDir)\MengeCore\BFSM;$(SrcDir)\MengeCore\resources;$(SrcDir)\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MENGECORE_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + false + + Level3 + EditAndContinue + + + tinyxml_d.lib;OpenGL32.lib;Glu32.lib;SDL_ttf.lib;SDL_image.lib;SDL.lib;libpng.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)MengeCore_d.dll + $(SolutionDir)..\..\resources\winlib;$(BuildRoot)\lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to executable folder + if not exist $(ExeDir) md $(ExeDir) +xcopy /y $(TargetPath) $(ExeDir) + + + + + + $(SrcDir)\include;$(SrcDir)\MengeCore;$(SrcDir)\MengeCore\Agents;$(SrcDir)\MengeCore\Runtime;$(SrcDir)\MengeCore\PluginEngine;$(SrcDir)\MengeCore\SceneGraph;$(SrcDir)\MengeCore\viewer;$(SrcDir)\MengeCore\BFSM;$(SrcDir)\MengeCore\resources;$(SrcDir)\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MENGECORE_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + false + + + tinyxml.lib;OpenGL32.lib;Glu32.lib;SDL_ttf.lib;SDL_image.lib;SDL.lib;libpng.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)MengeCore.dll + $(SolutionDir)..\..\resources\winlib;$(BuildRoot)\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to executable folder + if not exist $(ExeDir) md $(ExeDir) +xcopy /y $(TargetPath) $(ExeDir) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + + + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + + + + + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c406daec-0886-4771-8dea-9d7329b46cc1} + false + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Menge/MengeCore.vcxproj.filters b/projects/VS2012/Menge/MengeCore.vcxproj.filters new file mode 100644 index 00000000..9707d3d2 --- /dev/null +++ b/projects/VS2012/Menge/MengeCore.vcxproj.filters @@ -0,0 +1,1380 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {888ecaad-9bf2-4cf4-95e6-20e7ce32a19b} + + + {1609fc15-a4db-46ea-bdca-503e5a937f7a} + + + {5b551c6e-0cde-460e-8293-20af8665e1a1} + + + {831d4166-bca7-4478-99f2-a02a6a1ba569} + + + {c875dc27-2fc9-4b62-83f1-f4e07a11183a} + + + {96f890b2-9898-4869-9b32-479161ace98a} + + + {a00863e6-cb11-4ffd-9412-ea28faa4e0bb} + + + {af49b163-d6b3-4951-a991-0ed4b710e058} + + + {23055bc5-78ed-476b-ae4d-35b7a757f8c0} + + + {12b87dc1-1afd-408c-9ac7-85d596e01c19} + + + {b784ded7-c893-430a-a103-084fdfe7e680} + + + {373f3281-9ab2-45bf-b088-89adc7dc2e14} + + + {3d337fd8-23f8-425c-becf-c0392dff7af1} + + + {d26c1ee8-795e-4601-9c81-30540180edba} + + + {c5d4ac1b-e64c-450b-b3aa-5e2364c917aa} + + + {54bd8952-f312-4847-b14f-8dfc3d480dc1} + + + {a6e6d0f4-cc55-4033-a217-c4bd8d84584e} + + + {e955d6aa-701b-408f-b2ed-450f48302c39} + + + {65499c4b-d50e-4fe9-b66b-5cd2e4ea48db} + + + {76894682-bcc2-4bf7-be8f-02453eddae3a} + + + {d55edd71-0ad9-4d17-8e60-f6cc9c4c8283} + + + {631e635f-0c3f-4265-9f0f-022af99805bd} + + + {304ad583-673b-4a0b-bac6-9b7f14c02e5f} + + + {8257deef-690f-46d4-bb4f-ad4e40641204} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {9e1340ab-5226-495c-8066-210a59da1936} + + + {a18866e4-f76e-4e31-a7a6-a054742f5e8d} + + + {1d9e0e3e-8edf-45a6-81b4-b1891f3c9a70} + + + {c0f587f4-ffee-424e-b0d6-0b967235b1e1} + + + {59ba3f7c-ad36-4de2-84aa-3508a4b16e98} + + + {18f99721-2dd5-425a-b5e2-c00e399dce19} + + + {84b759ef-0643-45a2-8abe-76edfe691946} + + + {cc1263ac-ad35-481a-9e7b-c4f011244c9a} + + + {07588ce5-df47-452f-a504-6440b6dfdb69} + + + {600536ec-e90d-4735-bf67-f00f5c399623} + + + {a08db023-ad49-4b6e-bbc4-311918eb73ad} + + + {7605c45a-33f1-40b6-b554-e68666f66fa7} + + + {13ecd2b0-9032-44b1-bbde-e71ae8199d32} + + + {91a3e3fc-6041-402b-a28d-2b669d7a0f9d} + + + {7e8d898d-8755-4db8-a235-9b23185399cb} + + + {e685c140-8dd7-43fb-9279-756100cecf9d} + + + {50465e01-1118-466f-a6cd-b1c3f434af75} + + + {c0b8e67c-ccd1-4790-bbaa-3a3af963046a} + + + {687f88f8-22d9-4b56-969f-22006e69abc7} + + + {192a9af3-e168-42b9-84be-b9df54ed5123} + + + {8450424c-665a-4e0d-8563-be9a7e340f62} + + + {b0027d52-805a-4c04-821f-2acde70511ec} + + + {fc6b9a9b-3045-47ea-a941-4863d5e1a770} + + + {1298e387-09ae-4805-a961-1d67b00864f7} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents + + + Source Files\Agents\Elevations + + + Source Files\Agents\Elevations + + + Source Files\Agents\Elevations + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\SpatialQueries + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\AgentGenerators + + + Source Files\Agents\ProfileSelectors + + + Source Files\Agents\ProfileSelectors + + + Source Files\Agents\ProfileSelectors + + + Source Files\Agents\State Selectors + + + Source Files\Agents\State Selectors + + + Source Files\Agents\State Selectors + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\Events + + + Source Files\Agents\ObstacleSets + + + Source Files\Agents\ObstacleSets + + + Source Files\Agents\ObstacleSets + + + Source Files\Agents\ObstacleSets + + + Source Files\Agents\ObstacleSets + + + Source Files\Agents\ObstacleSets + + + Source Files\Math + + + Source Files\Math + + + Source Files\Math + + + Source Files\Math + + + Source Files\Math + + + Source Files\Math + + + Source Files\PluginEngine + + + Source Files\PluginEngine + + + Source Files\PluginEngine + + + Source Files\PluginEngine + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\SceneGraph + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Runtime + + + Source Files\Viewer + + + Source Files\Viewer + + + Source Files\Viewer + + + Source Files\Viewer + + + Source Files\Viewer + + + Source Files\Viewer + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM + + + Source Files\BFSM\Actions + + + Source Files\BFSM\Actions + + + Source Files\BFSM\Actions + + + Source Files\BFSM\Actions + + + Source Files\BFSM\Actions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\Transitions + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\VelComponents + + + Source Files\BFSM\Tasks + + + Source Files\BFSM\Tasks + + + Source Files\BFSM\Tasks + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\Goals + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\GoalSelectors + + + Source Files\BFSM\VelModifiers + + + Source Files\BFSM\VelModifiers + + + Source Files\BFSM\VelModifiers + + + Source Files\BFSM\VelModifiers + + + Source Files\orca + + + Source Files\orca + + + Source Files\orca + + + Source Files\orca + + + Source Files\pedvo + + + Source Files\pedvo + + + Source Files\pedvo + + + Source Files\pedvo + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + Source Files\resources + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents + + + Header Files\Agents\Elevations + + + Header Files\Agents\Elevations + + + Header Files\Agents\Elevations + + + Header Files\Agents\Elevations + + + Header Files\Agents\Elevations + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\SpatialQueries + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\AgentGenerators + + + Header Files\Agents\ProfileSelectors + + + Header Files\Agents\ProfileSelectors + + + Header Files\Agents\ProfileSelectors + + + Header Files\Agents\ProfileSelectors + + + Header Files\Agents\StateSelectors + + + Header Files\Agents\StateSelectors + + + Header Files\Agents\StateSelectors + + + Header Files\Agents\StateSelectors + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\Events + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Agents\ObstacleSets + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\Math + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\PluginEngine + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\SceneGraph + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Runtime + + + Header Files\Viewer + + + Header Files\Viewer + + + Header Files\Viewer + + + Header Files\Viewer + + + Header Files\Viewer + + + Header Files\Viewer + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Actions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\Transitions + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\VelComponents + + + Header Files\BFSM\Tasks + + + Header Files\BFSM\Tasks + + + Header Files\BFSM\Tasks + + + Header Files\BFSM\Tasks + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\Goals + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\GoalSelectors + + + Header Files\BFSM\VelModifiers + + + Header Files\BFSM\VelModifiers + + + Header Files\BFSM\VelModifiers + + + Header Files\BFSM\VelModifiers + + + Header Files\BFSM\VelModifiers + + + Header Files\orca + + + Header Files\orca + + + Header Files\orca + + + Header Files\orca + + + Header Files\orca + + + Header Files\orca + + + Header Files\orca + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\pedvo + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + Header Files\resources + + + \ No newline at end of file diff --git a/projects/VS2012/Menge/menge.vcxproj b/projects/VS2012/Menge/menge.vcxproj new file mode 100644 index 00000000..64e786ae --- /dev/null +++ b/projects/VS2012/Menge/menge.vcxproj @@ -0,0 +1,126 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B6CABAC3-735C-4046-97D5-DB2E9621F8C1} + simple + Win32Proj + + + + Application + v110 + Unicode + true + + + Application + v110 + Unicode + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(ExeDir)\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + $(ExeDir)\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(SrcDir)\;$(SrcDir)\include;$(SrcDir)\MengeCore;$(SrcDir)\MengeCore\BFSM;$(SrcDir)\MengeCore\viewer;$(SrcDir)\MengeCore\SceneGraph;$(SrcDir)\MengeCore\Math;$(SrcDir)\MengeCore\Agents;$(SrcDir)\MengeCore\Runtime;$(SrcDir)\MengeCore\PluginEngine;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + tinyxml_d.lib;MengeCore_d.lib;OpenGL32.Lib;GlU32.lib;SDL.lib;SDLmain.lib;SDL_image.lib;SDL_ttf.lib;libpng.lib;zlib.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(BuildRoot)\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + xcopy "$(SolutionDir)..\..\resources\win\*.*" "$(ExeDir)" /d /y +xcopy "$(SolutionDir)..\..\resources\common\*.*" "$(ExeDir)" /d /y + + + + + MaxSpeed + $(SrcDir)\;$(SrcDir)\include;$(SrcDir)\MengeCore;$(SrcDir)\MengeCore\BFSM;$(SrcDir)\MengeCore\viewer;$(SrcDir)\MengeCore\SceneGraph;$(SrcDir)\MengeCore\Math;$(SrcDir)\MengeCore\Agents;$(SrcDir)\MengeCore\Runtime;$(SrcDir)\MengeCore\PluginEngine;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + false + + + tinyxml.lib;MengeCore.lib;OpenGL32.Lib;GlU32.lib;SDL.lib;SDLmain.lib;SDL_image.lib;SDL_ttf.lib;libpng.lib;zlib.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(BuildRoot)\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + xcopy "$(SolutionDir)..\..\resources\win\*.*" "$(ExeDir)" /d /y +xcopy "$(SolutionDir)..\..\resources\common\*.*" "$(ExeDir)" /d /y + + + + + + + + + + + + + {f5b90b6a-8e12-496e-99eb-3ce9cbb79142} + false + + + {c406daec-0886-4771-8dea-9d7329b46cc1} + false + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Menge/menge.vcxproj.filters b/projects/VS2012/Menge/menge.vcxproj.filters new file mode 100644 index 00000000..b98d6528 --- /dev/null +++ b/projects/VS2012/Menge/menge.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Menge/tinyxml_lib.vcxproj b/projects/VS2012/Menge/tinyxml_lib.vcxproj new file mode 100644 index 00000000..cbd04867 --- /dev/null +++ b/projects/VS2012/Menge/tinyxml_lib.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + tinyxml + {C406DAEC-0886-4771-8DEA-9D7329B46CC1} + + + + StaticLibrary + v110 + false + MultiByte + + + StaticLibrary + v110 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + + + + + + + MaxSpeed + OnlyExplicitInline + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(ProjectDir)Build\tinyxml_lib.pch + $(IntDir) + $(IntDir) + $(IntDir)vc80.pdb + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0407 + + + $(BuildRoot)\lib\tinyxml.lib + true + + + true + $(IntDir)$(ProjectName).bsc + + + + + echo $(BuildRoot) + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(ProjectDir)Build\tinyxml_lib.pch + $(IntDir) + $(IntDir) + $(IntDir)vc80.pdb + true + Level4 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0407 + + + $(BuildRoot)\lib\tinyxml_d.lib + true + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Menge/tinyxml_lib.vcxproj.filters b/projects/VS2012/Menge/tinyxml_lib.vcxproj.filters new file mode 100644 index 00000000..642142ff --- /dev/null +++ b/projects/VS2012/Menge/tinyxml_lib.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {a9ffe213-80b7-48bd-a5f3-6e29d60c8441} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {2b1b7f26-7627-44db-90b5-57b684c79be1} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtDummy.vcxproj b/projects/VS2012/Plugins/AgtDummy.vcxproj new file mode 100644 index 00000000..0f41c7ca --- /dev/null +++ b/projects/VS2012/Plugins/AgtDummy.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {77BE22D2-25E3-4025-8512-9BB5015ED73F} + DummyPedestrians + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DUMMY_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DUMMY_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtDummy.vcxproj.filters b/projects/VS2012/Plugins/AgtDummy.vcxproj.filters new file mode 100644 index 00000000..1470282a --- /dev/null +++ b/projects/VS2012/Plugins/AgtDummy.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtHelbing.vcxproj b/projects/VS2012/Plugins/AgtHelbing.vcxproj new file mode 100644 index 00000000..8093bd2c --- /dev/null +++ b/projects/VS2012/Plugins/AgtHelbing.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2090832D-3620-4E86-904D-08632C3D1AA0} + HelbingPedestrians + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;HELBING_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;HELBING_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtHelbing.vcxproj.filters b/projects/VS2012/Plugins/AgtHelbing.vcxproj.filters new file mode 100644 index 00000000..5197cf9a --- /dev/null +++ b/projects/VS2012/Plugins/AgtHelbing.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtJohansson.vcxproj b/projects/VS2012/Plugins/AgtJohansson.vcxproj new file mode 100644 index 00000000..c565d800 --- /dev/null +++ b/projects/VS2012/Plugins/AgtJohansson.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F} + JohanssonPedestrians + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;JOHANSSON_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;JOHANSSON_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtJohansson.vcxproj.filters b/projects/VS2012/Plugins/AgtJohansson.vcxproj.filters new file mode 100644 index 00000000..8845c54b --- /dev/null +++ b/projects/VS2012/Plugins/AgtJohansson.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtKaramouzas.vcxproj b/projects/VS2012/Plugins/AgtKaramouzas.vcxproj new file mode 100644 index 00000000..3c5a1722 --- /dev/null +++ b/projects/VS2012/Plugins/AgtKaramouzas.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4} + AgtKaramouzas + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;KARAMOUZAS_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;KARAMOUZAS_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtKaramouzas.vcxproj.filters b/projects/VS2012/Plugins/AgtKaramouzas.vcxproj.filters new file mode 100644 index 00000000..5e35ed60 --- /dev/null +++ b/projects/VS2012/Plugins/AgtKaramouzas.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtZanlungo.vcxproj b/projects/VS2012/Plugins/AgtZanlungo.vcxproj new file mode 100644 index 00000000..5448288c --- /dev/null +++ b/projects/VS2012/Plugins/AgtZanlungo.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F} + AgtZanlungo + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;ZANLUNGO_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;ZANLUNGO_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/AgtZanlungo.vcxproj.filters b/projects/VS2012/Plugins/AgtZanlungo.vcxproj.filters new file mode 100644 index 00000000..c831c7f5 --- /dev/null +++ b/projects/VS2012/Plugins/AgtZanlungo.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Aircraft.vcxproj b/projects/VS2012/Plugins/Aircraft.vcxproj new file mode 100644 index 00000000..0f05d11d --- /dev/null +++ b/projects/VS2012/Plugins/Aircraft.vcxproj @@ -0,0 +1,124 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54} + HelbingPedestrians + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Aircraft.vcxproj.filters b/projects/VS2012/Plugins/Aircraft.vcxproj.filters new file mode 100644 index 00000000..562e1022 --- /dev/null +++ b/projects/VS2012/Plugins/Aircraft.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Formations.vcxproj b/projects/VS2012/Plugins/Formations.vcxproj new file mode 100644 index 00000000..f1689acd --- /dev/null +++ b/projects/VS2012/Plugins/Formations.vcxproj @@ -0,0 +1,126 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B321C48F-6A77-4949-AEF3-F313A31D357F} + Formations + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FORMATIONS_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FORMATIONS_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Formations.vcxproj.filters b/projects/VS2012/Plugins/Formations.vcxproj.filters new file mode 100644 index 00000000..d4da2903 --- /dev/null +++ b/projects/VS2012/Plugins/Formations.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/FundDiag.vcxproj b/projects/VS2012/Plugins/FundDiag.vcxproj new file mode 100644 index 00000000..12d20ce8 --- /dev/null +++ b/projects/VS2012/Plugins/FundDiag.vcxproj @@ -0,0 +1,122 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A} + FundDiag + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FDMODIFIER_EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FDMODIFIER_EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/FundDiag.vcxproj.filters b/projects/VS2012/Plugins/FundDiag.vcxproj.filters new file mode 100644 index 00000000..a634fcee --- /dev/null +++ b/projects/VS2012/Plugins/FundDiag.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Plugins12.sln b/projects/VS2012/Plugins/Plugins12.sln new file mode 100644 index 00000000..bf6bb9ba --- /dev/null +++ b/projects/VS2012/Plugins/Plugins12.sln @@ -0,0 +1,86 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtKaramouzas", "AgtKaramouzas.vcxproj", "{4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtDummy", "AgtDummy.vcxproj", "{77BE22D2-25E3-4025-8512-9BB5015ED73F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtHelbing", "AgtHelbing.vcxproj", "{2090832D-3620-4E86-904D-08632C3D1AA0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtJohansson", "AgtJohansson.vcxproj", "{77491B89-9A8B-4E69-B19A-58AFED2A6E2F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgtZanlungo", "AgtZanlungo.vcxproj", "{5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Terrain", "Terrain.vcxproj", "{C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Formations", "Formations.vcxproj", "{B321C48F-6A77-4949-AEF3-F313A31D357F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FundDiag", "FundDiag.vcxproj", "{2CB742B3-536D-4E39-BA12-6D029E8FCA2A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Aircraft", "Aircraft.vcxproj", "{2B4A4D3D-27A9-4C27-95BE-21737C22EA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + ReleaseST|Win32 = ReleaseST|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Debug|Win32.Build.0 = Debug|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Release|Win32.ActiveCfg = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.Release|Win32.Build.0 = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {4AF6F39F-2653-4E7E-AF2E-EFD37B1C1AD4}.ReleaseST|Win32.Build.0 = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Debug|Win32.ActiveCfg = Debug|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Debug|Win32.Build.0 = Debug|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Release|Win32.ActiveCfg = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.Release|Win32.Build.0 = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {77BE22D2-25E3-4025-8512-9BB5015ED73F}.ReleaseST|Win32.Build.0 = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Debug|Win32.ActiveCfg = Debug|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Debug|Win32.Build.0 = Debug|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Release|Win32.ActiveCfg = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.Release|Win32.Build.0 = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2090832D-3620-4E86-904D-08632C3D1AA0}.ReleaseST|Win32.Build.0 = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Debug|Win32.ActiveCfg = Debug|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Debug|Win32.Build.0 = Debug|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Release|Win32.ActiveCfg = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.Release|Win32.Build.0 = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {77491B89-9A8B-4E69-B19A-58AFED2A6E2F}.ReleaseST|Win32.Build.0 = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Debug|Win32.ActiveCfg = Debug|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Debug|Win32.Build.0 = Debug|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Release|Win32.ActiveCfg = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.Release|Win32.Build.0 = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {5AAD587D-54BE-46D6-A9C5-C3BE1B82127F}.ReleaseST|Win32.Build.0 = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Debug|Win32.Build.0 = Debug|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Release|Win32.ActiveCfg = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.Release|Win32.Build.0 = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A}.ReleaseST|Win32.Build.0 = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Debug|Win32.ActiveCfg = Debug|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Debug|Win32.Build.0 = Debug|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Release|Win32.ActiveCfg = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.Release|Win32.Build.0 = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {B321C48F-6A77-4949-AEF3-F313A31D357F}.ReleaseST|Win32.Build.0 = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Debug|Win32.Build.0 = Debug|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Release|Win32.ActiveCfg = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.Release|Win32.Build.0 = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2CB742B3-536D-4E39-BA12-6D029E8FCA2A}.ReleaseST|Win32.Build.0 = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Debug|Win32.Build.0 = Debug|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Release|Win32.ActiveCfg = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.Release|Win32.Build.0 = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.ReleaseST|Win32.ActiveCfg = Release|Win32 + {2B4A4D3D-27A9-4C27-95BE-21737C22EA54}.ReleaseST|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/VS2012/Plugins/Sample.vcxproj b/projects/VS2012/Plugins/Sample.vcxproj new file mode 100644 index 00000000..9f558769 --- /dev/null +++ b/projects/VS2012/Plugins/Sample.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A} + Sample + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;$(MengeSrc)MengeCore\resources;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;$(MengeSrc)MengeCore\resources;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Sample.vcxproj.filters b/projects/VS2012/Plugins/Sample.vcxproj.filters new file mode 100644 index 00000000..dc2b5456 --- /dev/null +++ b/projects/VS2012/Plugins/Sample.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Terrain.vcxproj b/projects/VS2012/Plugins/Terrain.vcxproj new file mode 100644 index 00000000..5bb7b3dc --- /dev/null +++ b/projects/VS2012/Plugins/Terrain.vcxproj @@ -0,0 +1,126 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C3A1CEBF-3091-471D-B682-71ABB8EA2F0A} + Terrain + Win32Proj + + + + DynamicLibrary + v110 + Unicode + true + + + DynamicLibrary + v110 + Unicode + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + true + $(ProjectName)_d + + + $(BuildRoot)\lib\ + $(BuildRoot)\$(ProjectName)\$(Configuration)\ + false + + + + Disabled + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;$(MengeSrc)MengeCore\resources;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + MengeCore_d.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml_d.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName)_d.dll + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins\debug md $(ExeDir)\plugins\debug +xcopy /y $(TargetPath) $(ExeDir)\plugins\debug\ + + + + + + $(MengeSrc);$(MengeSrc)include;$(MengeSrc)tinyxml;$(MengeSrc)MengeCore;$(MengeSrc)MengeCore\Math;$(MengeSrc)MengeCore\BFSM;$(MengeSrc)MengeCore\SceneGraph;$(MengeSrc)MengeCore\Runtime;$(MengeSrc)MengeCore\PluginEngine;$(MengeSrc)MengeCore\Agents;$(MengeSrc)MengeCore\resources;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPORT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + MengeCore.lib;OpenGL32.lib;SDL_ttf.lib;GLU32.lib;SDL.lib;tinyxml.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\resources\winlib;$(MengeLib);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + Copy DLL to exectuable folder + if not exist $(ExeDir)\plugins md $(ExeDir)\plugins +xcopy /y $(TargetPath) $(ExeDir)\plugins\ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/VS2012/Plugins/Terrain.vcxproj.filters b/projects/VS2012/Plugins/Terrain.vcxproj.filters new file mode 100644 index 00000000..dedd8222 --- /dev/null +++ b/projects/VS2012/Plugins/Terrain.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/VS2012/pluginMacros.props b/projects/VS2012/pluginMacros.props new file mode 100644 index 00000000..5acc8c89 --- /dev/null +++ b/projects/VS2012/pluginMacros.props @@ -0,0 +1,13 @@ + + + + + + $(SolutionDir)..\..\..\src\Menge\ + $(SolutionDir)..\Menge\build\lib + $(SolutionDir)..\..\..\src\Plugins + + + + + diff --git a/projects/VS2012/userMacros.props b/projects/VS2012/userMacros.props new file mode 100644 index 00000000..62719ccd --- /dev/null +++ b/projects/VS2012/userMacros.props @@ -0,0 +1,25 @@ + + + + + + $(SolutionDir)\build + $(SolutionDir)..\..\..\Exe + $(SolutionDir)..\..\..\src\Menge + + + <_ProjectFileVersion>11.0.50727.1 + + + + + $(BuildRoot) + + + $(ExeDir) + + + $(SrcDir) + + + \ No newline at end of file diff --git a/projects/g++/CMakeLists.txt b/projects/g++/CMakeLists.txt new file mode 100644 index 00000000..2fab2016 --- /dev/null +++ b/projects/g++/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 2.8) + +project(FULL_MENGE_PED_SIM) + +# Model dlls +ADD_SUBDIRECTORY(Menge) +ADD_SUBDIRECTORY(Plugins) + diff --git a/projects/g++/Makefile b/projects/g++/Makefile new file mode 100644 index 00000000..edcd670c --- /dev/null +++ b/projects/g++/Makefile @@ -0,0 +1,34 @@ +.PHONY: release debug clean clean-release clean-debug install + +DIRS:= build build/release build/debug + +all: $(DIRS) release + + +$(DIRS): + mkdir $@ + + +release: + ( cd build/release && cmake -DCMAKE_BUILD_TYPE=release ../.. && $(MAKE) --no-print-directory && make --no-print-directory install) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* + +debug: + ( cd build/debug && cmake -DCMAKE_BUILD_TYPE=debug ../.. && $(MAKE) --no-print-directory && make --no-print-directory install) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* + +clean: clean-release clean-debug + +clean-release: + ( cd build/release && $(MAKE) --no-print-directory clean ) + +clean-debug: + ( cd build/debug && $(MAKE) --no-print-directory clean ) + + +#release: +# ( cd build/release && cmake -DCMAKE_BUILD_TYPE=release ../.. && $(MAKE) --no-print-directory && make --no-print-directory install) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* diff --git a/projects/g++/Menge/CMakeLists.txt b/projects/g++/Menge/CMakeLists.txt new file mode 100644 index 00000000..da2db529 --- /dev/null +++ b/projects/g++/Menge/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 2.8) + +project(MENGE) + +set(MENGE_SRC_DIR ${CMAKE_SOURCE_DIR}/../../src/Menge) +set(MENGE_EXE_DIR ${CMAKE_SOURCE_DIR}/../../Exe) +set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/) +link_directories (${LIBRARY_OUTPUT_PATH}/) + +#Where to find the header files +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/include) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/BFSM) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/viewer) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/SceneGraph) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/Math) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/Agents) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/Runtime) +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/PluginEngine) + +set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fpermissive" ) + + +#find the correct OpenMP flag +FIND_PACKAGE(OpenMP) +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OpenMP_CXX_FLAGS} -fpermissive -DNDEBUG") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +FIND_PACKAGE(SDL) +if(NOT SDL_FOUND) + message(STATUS "I will try to link against local libraries") + INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/include) + LINK_DIRECTORIES (${MENGE_SRC_DIR}/lib) + SET(SDL_LIBRARY "SDL") + SET(SDLMAIN_LIBRARY "SDLmain") +else() + INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR}) +endif() + +FIND_PACKAGE(SDL_ttf) +if(NOT SDLTTF_FOUND) + MESSAGE(STATUS "I will try to link against local libraries") + INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/include) + LINK_DIRECTORIES (${MENGE_SRC_DIR}/lib) + SET(SDLTTF_LIBRARY "SDL_ttf") +else() + INCLUDE_DIRECTORIES(${SDLTTF_INCLUDE_DIR}) +endif() + +FIND_PACKAGE(SDL_image) +if(NOT SDLIMAGE_FOUND) + message(STATUS "I will try to link against local libraries") + INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/include) + LINK_DIRECTORIES (${MENGE_SRC_DIR}/lib) + SET(SDLIMAGE_LIBRARY SDL_image) +else() + INCLUDE_DIRECTORIES(${SDLIMAGE_INCLUDE_DIR}) +endif() + +FIND_PACKAGE(OpenGL REQUIRED) +if(OPENGL_FOUND) + INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) +endif() + +FIND_PACKAGE(PNG REQUIRED) + +ADD_SUBDIRECTORY(tinyxml) +ADD_SUBDIRECTORY(MengeCore) +ADD_SUBDIRECTORY(mengeMain) + +file( + GLOB + EXTRA_FILES + ${CMAKE_SOURCE_DIR}/../resources/linux/* + ${CMAKE_SOURCE_DIR}/../resources/common/* +) + +file( COPY ${EXTRA_FILES} DESTINATION ${MENGE_EXE_DIR} ) + +set( CMAKE_INSTALL_ALWAYS true ) diff --git a/projects/g++/Menge/Makefile b/projects/g++/Menge/Makefile new file mode 100644 index 00000000..a8814f82 --- /dev/null +++ b/projects/g++/Menge/Makefile @@ -0,0 +1,192 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canoncical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /playpen/fsm/projects/g++/Menge + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /playpen/fsm/projects/g++/Menge + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /playpen/fsm/projects/g++/Menge/CMakeFiles /playpen/fsm/projects/g++/Menge/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /playpen/fsm/projects/g++/Menge/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named tinyxml + +# Build rule for target. +tinyxml: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 tinyxml +.PHONY : tinyxml + +# fast build rule for target. +tinyxml/fast: + $(MAKE) -f tinyxml/CMakeFiles/tinyxml.dir/build.make tinyxml/CMakeFiles/tinyxml.dir/build +.PHONY : tinyxml/fast + +#============================================================================= +# Target rules for targets named mengeCore + +# Build rule for target. +mengeCore: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 mengeCore +.PHONY : mengeCore + +# fast build rule for target. +mengeCore/fast: + $(MAKE) -f MengeCore/CMakeFiles/mengeCore.dir/build.make MengeCore/CMakeFiles/mengeCore.dir/build +.PHONY : mengeCore/fast + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... tinyxml" + @echo "... mengeCore" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/projects/g++/Menge/MengeCore/CMakeLists.txt b/projects/g++/Menge/MengeCore/CMakeLists.txt new file mode 100644 index 00000000..afda83fc --- /dev/null +++ b/projects/g++/Menge/MengeCore/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.8) + +project(MENGE_CORE) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGE_EXE_DIR}) + +INCLUDE_DIRECTORIES (${MENGE_SRC_DIR}/MengeCore/resources) + +file( + GLOB_RECURSE + source_files + ${MENGE_SRC_DIR}/MengeCore/*.cpp + ${MENGE_SRC_DIR}/MengeCore/*.h +) + + +add_library( + mengeCore + SHARED + ${database_files} + ${source_files} +) + +target_link_libraries ( mengeCore dl ) + +install( TARGETS mengeCore DESTINATION ${LIBRARY_OUTPUT_PATH} ) \ No newline at end of file diff --git a/projects/g++/Menge/cmake-clean.py b/projects/g++/Menge/cmake-clean.py new file mode 100644 index 00000000..d3db0113 --- /dev/null +++ b/projects/g++/Menge/cmake-clean.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# +# Copyright (c) 2012-2012 Tom Schutter +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +""" +Clean cmake generated files. +""" + +import optparse +import os +import shutil +import subprocess +import sys + +# Do not cleanup anything in these subdirectories. +PRUNE_DIRS = [".svn", ".git", "CVS"] + + +def make_clean(directory): + """Run 'make clean' in directory. + + Arguments: + - `directory`: target directory + """ + args = [ + "make", + "--directory=%s" % directory, + "--quiet", + "clean" + ] + process = subprocess.Popen(args) + return process.wait() + + +def clean( + directory + ): + """Clean cmake files. + + Arguments: + - `directory`: target directory + """ + + # Toplevel files. + for filename in [ + "CMakeCache.txt", + "CPackConfig.cmake", + "CPackSourceConfig.cmake", + "install_manifest.txt" + ]: + pathname = os.path.join(directory, filename) + if os.path.exists(pathname): + os.remove(pathname) + + # Toplevel directories. + for dirname in ["_CPack_Packages"]: + pathname = os.path.join(directory, dirname) + if os.path.exists(pathname): + shutil.rmtree(pathname) + + # CMakeFiles, Makefile, cmake_install.cmake. + for dirpath, dirnames, filenames in os.walk(directory): + # Prune subdirs. + for dirname in dirnames: + if dirname in PRUNE_DIRS: + dirnames.remove(dirname) + + if "CMakeFiles" in dirnames: + for filename in ["Makefile", "cmake_install.cmake"]: + if filename in filenames: + pathname = os.path.join(dirpath, filename) + if os.path.exists(pathname): + os.remove(pathname) + shutil.rmtree(os.path.join(dirpath, "CMakeFiles")) + dirnames.remove("CMakeFiles") + + # Remove empty directories. The "repeat" construct is needed + # because the dirnames list for the parent is generated before the + # parent is processed. When a directory is removed, there is no + # way to remove it from the parent's dirnames list. Note that + # setting topdown=False will not help here, and it complicates the + # pruning logic. + repeat = True + while repeat: + repeat = False + for dirpath, dirnames, filenames in os.walk(directory): + # We must check for emptiness before pruning. Otherwise + # we could try to remove a directory that contains only + # prunable subdirs. + if len(dirnames) == 0 and len(filenames) == 0: + os.rmdir(dirpath) + repeat = True + + # Prune subdirs. + for dirname in dirnames: + if dirname in PRUNE_DIRS: + dirnames.remove(dirname) + + +def main(): + """main""" + option_parser = optparse.OptionParser( + usage="usage: %prog [DIR...]\n" + + " Clean cmake generated files." + ) + + (_, args) = option_parser.parse_args() + if len(args) == 0: + args.append(".") + + for arg in args: + make_clean(arg) + clean(arg) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/projects/g++/Menge/mengeMain/CMakeLists.txt b/projects/g++/Menge/mengeMain/CMakeLists.txt new file mode 100644 index 00000000..eb0367f4 --- /dev/null +++ b/projects/g++/Menge/mengeMain/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 2.8) + +project(Menge) + +set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGE_EXE_DIR}) + +file( + GLOB_RECURSE + source_files + ${MENGE_SRC_DIR}/mengeMain/*.cpp + ${MENGE_SRC_DIR}/mengeMain/*.h +) + +add_executable( + menge + ${source_files} +) + +target_link_libraries (menge mengeCore tinyxml ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ${PNG_LIBRARY}) + +#file( COPY ${CMAKE_SOURCE_DIR}/../resources/linux DESTINATION ${MENGE_EXE_DIR} ) +#file( COPY ${CMAKE_SOURCE_DIR}/../resources/common DESTINATION ${MENGE_EXE_DIR} ) +#install( TARGETS menge DESTINATION ${MENGE_EXE_DIR} ) diff --git a/projects/g++/Menge/tinyxml/CMakeLists.txt b/projects/g++/Menge/tinyxml/CMakeLists.txt new file mode 100644 index 00000000..7e5083b1 --- /dev/null +++ b/projects/g++/Menge/tinyxml/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 2.8) + +project(tinyxml) + +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) + +file( + GLOB_RECURSE + source_files + ${MENGE_SRC_DIR}/tinyxml/*.cpp + ${MENGE_SRC_DIR}/tinyxml/*.h +) + + +add_library( + tinyxml + STATIC + ${source_files} +) + +#install( TARGETS tinyxml DESTINATION ${MENGE_SRC_DIR}/lib ) \ No newline at end of file diff --git a/projects/g++/Plugins/AgtDummy/CMakeLists.txt b/projects/g++/Plugins/AgtDummy/CMakeLists.txt new file mode 100644 index 00000000..ef203817 --- /dev/null +++ b/projects/g++/Plugins/AgtDummy/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 2.8) + +project(DummyModel) + +add_definitions( -DDUMMY_EXPORT ) + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/AgtDummy/*.cpp + ${PLUGIN_SOURCE_DIR}/AgtDummy/*.h +) + +add_library( + dummyPed + SHARED + ${source_files} +) + +target_link_libraries (dummyPed mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/AgtHelbing/CMakeLists.txt b/projects/g++/Plugins/AgtHelbing/CMakeLists.txt new file mode 100644 index 00000000..44e8b78e --- /dev/null +++ b/projects/g++/Plugins/AgtHelbing/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +project(HelbingModel) + +add_definitions( -DHELBING_EXPORT ) + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/AgtHelbing/*.cpp + ${PLUGIN_SOURCE_DIR}/AgtHelbing/*.h +) + +add_library( + helbingPed + SHARED + ${source_files} +) + +target_link_libraries (helbingPed mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) diff --git a/projects/g++/Plugins/AgtJohansson/CMakeLists.txt b/projects/g++/Plugins/AgtJohansson/CMakeLists.txt new file mode 100644 index 00000000..de9a302c --- /dev/null +++ b/projects/g++/Plugins/AgtJohansson/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +project(JohanssonModel) + +add_definitions( -DJOHANSSON_EXPORT ) + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/AgtJohansson/*.cpp + ${PLUGIN_SOURCE_DIR}/AgtJohansson/*.h +) + +add_library( + johanssonPed + SHARED + ${source_files} +) + +target_link_libraries (johanssonPed mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) diff --git a/projects/g++/Plugins/AgtKaramouzas/CMakeLists.txt b/projects/g++/Plugins/AgtKaramouzas/CMakeLists.txt new file mode 100644 index 00000000..8318b636 --- /dev/null +++ b/projects/g++/Plugins/AgtKaramouzas/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 2.8) + +project(KaramouzasModel) + +add_definitions( -DKARAMOUZAS_EXPORT ) + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/AgtKaramouzas/*.cpp + ${PLUGIN_SOURCE_DIR}/AgtKaramouzas/*.h +) + +add_library( + karamouzasPed + SHARED + ${source_files} +) + +target_link_libraries (karamouzasPed mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/AgtZanlungo/CMakeLists.txt b/projects/g++/Plugins/AgtZanlungo/CMakeLists.txt new file mode 100644 index 00000000..ce66a2dd --- /dev/null +++ b/projects/g++/Plugins/AgtZanlungo/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +project(ZanlungoModel) + +add_definitions( -DZANLUNGO_EXPORT ) + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/AgtZanlungo/*.cpp + ${PLUGIN_SOURCE_DIR}/AgtZanlungo/*.h +) + +add_library( + zanlungoPed + SHARED + ${source_files} +) + +target_link_libraries (zanlungoPed mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) diff --git a/projects/g++/Plugins/CMakeLists.txt b/projects/g++/Plugins/CMakeLists.txt new file mode 100644 index 00000000..b74247ca --- /dev/null +++ b/projects/g++/Plugins/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 2.8) + +project(PED_PLUGINS) + +set(MENGE_EXE_DIR ${CMAKE_SOURCE_DIR}/../../Exe) +if ( ${CMAKE_BUILD_TYPE} MATCHES "Debug" ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGE_EXE_DIR}/plugins/debug) +else ( ${CMAKE_BUILD_TYPE} MATCHES "Debug" ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGE_EXE_DIR}/plugins) +ENDIF ( ${CMAKE_BUILD_TYPE} MATCHES "Debug" ) +set(PLUGIN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../../src/Plugins) +set(MENGE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../../src/Menge) +set(MENGE_LIB_DIR ${CMAKE_BINARY_DIR}/lib ) + +link_directories( ${MENGE_LIB_DIR}/) + +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/BFSM) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/viewer) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/SceneGraph) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/Math) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/Agents) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/Runtime) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/resources) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/MengeCore/PluginEngine) +INCLUDE_DIRECTORIES (${MENGE_SOURCE_DIR}/tinyxml) + +#find the correct OpenMP flag +FIND_PACKAGE(OpenMP) +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OpenMP_CXX_FLAGS} -fpermissive") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +# Model dlls +ADD_SUBDIRECTORY(aircraft) +ADD_SUBDIRECTORY(FundamentalDiagram) +ADD_SUBDIRECTORY(Terrain) +ADD_SUBDIRECTORY(Formations) +ADD_SUBDIRECTORY(AgtDummy) +ADD_SUBDIRECTORY(AgtHelbing) +ADD_SUBDIRECTORY(AgtJohansson) +ADD_SUBDIRECTORY(AgtKaramouzas) +ADD_SUBDIRECTORY(AgtZanlungo) +#ADD_SUBDIRECTORY(Sample) + +set( CMAKE_INSTALL_ALWAYS true ) \ No newline at end of file diff --git a/projects/g++/Plugins/Formations/CMakeLists.txt b/projects/g++/Plugins/Formations/CMakeLists.txt new file mode 100644 index 00000000..39d916f4 --- /dev/null +++ b/projects/g++/Plugins/Formations/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8) + +project(FormationPlugin) + +add_definitions( -DFORMATIONS_EXPORT ) + + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/Formations/*.cpp + ${PLUGIN_SOURCE_DIR}/Formations/*.h +) + +add_library( + formations + SHARED + ${source_files} +) + +target_link_libraries (formations mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/FundamentalDiagram/CMakeLists.txt b/projects/g++/Plugins/FundamentalDiagram/CMakeLists.txt new file mode 100644 index 00000000..c13754c7 --- /dev/null +++ b/projects/g++/Plugins/FundamentalDiagram/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8) + +project(FDPlugin) + +add_definitions( -DFDMODIFIER_EXPORT ) + + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/FundamentalDiagram/*.cpp + ${PLUGIN_SOURCE_DIR}/FundamentalDiagram/*.h +) + +add_library( + fundDiag + SHARED + ${source_files} +) + +target_link_libraries (fundDiag mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/Makefile b/projects/g++/Plugins/Makefile new file mode 100644 index 00000000..f4d8e202 --- /dev/null +++ b/projects/g++/Plugins/Makefile @@ -0,0 +1,34 @@ +.PHONY: release debug clean clean-release clean-debug install + +DIRS:= ../build ../build/release ../build/debug ../build/release/PedPlugins ../build/debug/PedPlugins + +all: $(DIRS) release + + +$(DIRS): + mkdir $@ + + +release: + ( cd ../build/release/PedPlugins && cmake -DCMAKE_BUILD_TYPE=release ../../../PedPlugins && $(MAKE) --no-print-directory ) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* + +debug: + ( cd ../build/debug/PedPlugins && cmake -DCMAKE_BUILD_TYPE=debug ../../../PedPlugins && $(MAKE) --no-print-directory) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* + +clean: clean-release clean-debug + +clean-release: + ( cd ../build/release && $(MAKE) --no-print-directory clean ) + +clean-debug: + ( cd ../build/debug && $(MAKE) --no-print-directory clean ) + + +#release: +# ( cd build/release && cmake -DCMAKE_BUILD_TYPE=release ../.. && $(MAKE) --no-print-directory && make --no-print-directory install) +# ctags -R --language-force=c++ *.* +# ctags -eR --language-force=c++ *.* diff --git a/projects/g++/Plugins/Sample/CMakeLists.txt b/projects/g++/Plugins/Sample/CMakeLists.txt new file mode 100644 index 00000000..c22554c2 --- /dev/null +++ b/projects/g++/Plugins/Sample/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8) + +project(SamplePlugin) + +add_definitions( -DEXPORT ) + + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/SampleProjectTemplate/*.cpp + ${PLUGIN_SOURCE_DIR}/SampleProjectTemplate/*.h +) + +add_library( + fundDiag + SHARED + ${source_files} +) + +target_link_libraries (sample mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/Terrain/CMakeLists.txt b/projects/g++/Plugins/Terrain/CMakeLists.txt new file mode 100644 index 00000000..3a46a542 --- /dev/null +++ b/projects/g++/Plugins/Terrain/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8) + +project(TerrainPlugin) + +add_definitions( -DEXPORT ) + + +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/Terrain/*.cpp + ${PLUGIN_SOURCE_DIR}/Terrain/*.h +) + +add_library( + terrain + SHARED + ${source_files} +) + +target_link_libraries (terrain mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/g++/Plugins/aircraft/CMakeLists.txt b/projects/g++/Plugins/aircraft/CMakeLists.txt new file mode 100644 index 00000000..dbea9e5b --- /dev/null +++ b/projects/g++/Plugins/aircraft/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8) + +project(AircraftPlugin) + +add_definitions( -DEXPORT ) + +message( STATUS "PluginSource={${PLUGIN_SOURCE_DIR}}" ) +file( + GLOB_RECURSE + source_files + ${PLUGIN_SOURCE_DIR}/aircraft/*.cpp + ${PLUGIN_SOURCE_DIR}/aircraft/*.h +) + +add_library( + aircraft + SHARED + ${source_files} +) + +target_link_libraries (aircraft mengeCore ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + diff --git a/projects/resources/common/arial.ttf b/projects/resources/common/arial.ttf new file mode 100644 index 00000000..ff0815cd Binary files /dev/null and b/projects/resources/common/arial.ttf differ diff --git a/projects/resources/common/log.css b/projects/resources/common/log.css new file mode 100644 index 00000000..ff2c1b51 --- /dev/null +++ b/projects/resources/common/log.css @@ -0,0 +1,53 @@ +table, th, td { + border-collapse:collapse; + border: 1px solid grey; +} +table { + table-layout : fixed; + width: 950 px; + max-width: 900 px; + background-color : #292929; +} +td { + min-width: 200px; +} +#content { + position : relative; +} +body, html { + background: #000000; + width: 1000px; + font-family: Arial; + font-size: 16px; + color: #C0C0C0; +} +h1 { + font-size : 50px; + line-height : 100px; + color : #FFFFFF; + border-bottom : 1px dotted #888888; +} +#logo { + position: absolute; + top: 0px; + right: 0px; +} +.divider { + background : #DDD; +} +.box { + padding : 0px; +} +.inf { + color: #C0C0C0; + min-width : 1000px; + max-width : 1000px; +} +.err { + color: #EE1100; + font-weight: bold +} +.war { + color: #FFCC00; + font-weight: bold +} \ No newline at end of file diff --git a/projects/resources/common/mengeLogo.png b/projects/resources/common/mengeLogo.png new file mode 100644 index 00000000..3fadf066 Binary files /dev/null and b/projects/resources/common/mengeLogo.png differ diff --git a/projects/resources/common/mengeLogo.psd b/projects/resources/common/mengeLogo.psd new file mode 100644 index 00000000..a34b5d60 Binary files /dev/null and b/projects/resources/common/mengeLogo.psd differ diff --git a/projects/resources/linux/allExamples b/projects/resources/linux/allExamples new file mode 100644 index 00000000..8c8b45c0 --- /dev/null +++ b/projects/resources/linux/allExamples @@ -0,0 +1,56 @@ +set -x + +./menge -p ../examples/core/tradeshow.xml +./menge -p ../examples/core/steerbench/surprise.xml +./menge -p ../examples/core/steerbench/4wayconfusion.xml +./menge -p ../examples/core/steerbench/curves.xml +./menge -p ../examples/core/steerbench/doorwayTwoway.xml +./menge -p ../examples/core/steerbench/doubleSqueeze.xml +./menge -p ../examples/core/steerbench/frogger.xml +./menge -p ../examples/core/steerbench/oncomingObstacle.xml +./menge -p ../examples/core/steerbench/simple.xml +./menge -p ../examples/core/steerbench/wallSqueeze.xml +./menge -p ../examples/core/pedModelSwap.xml -m orca -t 0.1 +./menge -p ../examples/core/pedModelSwap.xml -m helbing -t 0.1 --subSteps 9 +./menge -p ../examples/core/pedModelSwap.xml -m karamouzas -t 0.1 --subSteps 9 +./menge -p ../examples/core/office.xml +./menge -p ../examples/core/globalNavSwap-vectorfield.xml +./menge -p ../examples/core/globalNavSwap-navmesh.xml +./menge -p ../examples/core/globalNavSwap-roadmap.xml +./menge -p ../examples/core/boolean.xml +./menge -p ../examples/core/bottleneck.xml +./menge -p ../examples/core/circle.xml +./menge -p ../examples/core/concave.xml +./menge -p ../examples/core/cross.xml +./menge -p ../examples/core/4square.xml +./menge -p ../examples/core/goalDistance.xml +./menge -p ../examples/core/headon.xml +./menge -p ../examples/core/maze-navmesh.xml +./menge -p ../examples/core/maze-roadmap.xml +./menge -p ../examples/core/maze-vectorfield.xml +./menge -p ../examples/core/navMesh.xml +./menge -p ../examples/core/obstacleSwitch.xml +./menge -p ../examples/core/periodic.xml +./menge -p ../examples/core/persistGoal.xml +./menge -p ../examples/core/randomGoal.xml +./menge -p ../examples/core/sharedGoal.xml +./menge -p ../examples/core/soccer.xml +./menge -p ../examples/core/stadium.xml +./menge -p ../examples/core/swap.xml +./menge -p ../examples/core/event.xml + +./menge -p ../examples/plugin/propertyX.xml +./menge -p ../examples/plugin/terrain.xml +./menge -p ../examples/plugin/aircraft/load/loadBack.xml +./menge -p ../examples/plugin/aircraft/load/loadByZone.xml +./menge -p ../examples/plugin/aircraft/load/loadFront.xml +./menge -p ../examples/plugin/aircraft/load/loadRandom.xml +./menge -p ../examples/plugin/aircraft/unload/simpleUnload.xml -t 0.1 --subSteps 9 +./menge -p ../examples/plugin/aircraft/unload/waitingAgent.xml +./menge -p ../examples/plugin/formation.xml +./menge -p ../examples/plugin/denseFormation.xml +./menge -p ../examples/plugin/formationChange.xml +./menge -p ../examples/plugin/formationNavigation.xml +./menge -p ../examples/plugin/fundDiag.xml + +./menge -p ../examples/hold/timer.xml \ No newline at end of file diff --git a/projects/resources/linux/runExample b/projects/resources/linux/runExample new file mode 100644 index 00000000..6eb7f057 --- /dev/null +++ b/projects/resources/linux/runExample @@ -0,0 +1,20 @@ +#!/bin/bash +if [ $# -lt 2 ]; then + echo + echo "You must specify the example name and the model name" + echo " You can optionall add arguments specifying duration and time step." + echo " Example:" + echo " ./runExample headon pedvo" + echo " ./runExample headon pedvo 30" + echo " ./runExample headon pedvo 30 0.01" +else + if [ $# = 2 ]; then + ./menge -b ../examples/$1B.xml -s ../examples/$1S.xml --view ../examples/$1V.xml -m $2 + else + if [ $# = 3 ]; then + ./menge -b ../examples/$1B.xml -s ../examples/$1S.xml --view ../examples/$1V.xml -m $2 -d $3 + else + ./menge -b ../examples/$1B.xml -s ../examples/$1S.xml --view ../examples/$1V.xml -m $2 -d $3 -t $4 + fi + fi +fi \ No newline at end of file diff --git a/projects/resources/win/SDL.dll b/projects/resources/win/SDL.dll new file mode 100644 index 00000000..a5da7bbd Binary files /dev/null and b/projects/resources/win/SDL.dll differ diff --git a/projects/resources/win/SDL_image.dll b/projects/resources/win/SDL_image.dll new file mode 100644 index 00000000..e891b167 Binary files /dev/null and b/projects/resources/win/SDL_image.dll differ diff --git a/projects/resources/win/SDL_ttf.dll b/projects/resources/win/SDL_ttf.dll new file mode 100644 index 00000000..9ba46bd0 Binary files /dev/null and b/projects/resources/win/SDL_ttf.dll differ diff --git a/projects/resources/win/allExamples.bat b/projects/resources/win/allExamples.bat new file mode 100644 index 00000000..7a5b6716 --- /dev/null +++ b/projects/resources/win/allExamples.bat @@ -0,0 +1,54 @@ +menge.exe -p ../examples/core/tradeshow.xml +menge.exe -p ../examples/core/steerbench/surprise.xml +menge.exe -p ../examples/core/steerbench/4wayconfusion.xml +menge.exe -p ../examples/core/steerbench/curves.xml +menge.exe -p ../examples/core/steerbench/doorwayTwoway.xml +menge.exe -p ../examples/core/steerbench/doubleSqueeze.xml +menge.exe -p ../examples/core/steerbench/frogger.xml +menge.exe -p ../examples/core/steerbench/oncomingObstacle.xml +menge.exe -p ../examples/core/steerbench/simple.xml +menge.exe -p ../examples/core/steerbench/wallSqueeze.xml +menge.exe -p ../examples/core/pedModelSwap.xml -m orca -t 0.1 +menge.exe -p ../examples/core/pedModelSwap.xml -m helbing -t 0.1 --subSteps 9 +menge.exe -p ../examples/core/pedModelSwap.xml -m karamouzas -t 0.1 --subSteps 9 +menge.exe -p ../examples/core/office.xml +menge.exe -p ../examples/core/globalNavSwap-vectorfield.xml +menge.exe -p ../examples/core/globalNavSwap-navmesh.xml +menge.exe -p ../examples/core/globalNavSwap-roadmap.xml +menge.exe -p ../examples/core/boolean.xml +menge.exe -p ../examples/core/bottleneck.xml +menge.exe -p ../examples/core/circle.xml +menge.exe -p ../examples/core/concave.xml +menge.exe -p ../examples/core/cross.xml +menge.exe -p ../examples/core/4square.xml +menge.exe -p ../examples/core/goalDistance.xml +menge.exe -p ../examples/core/headon.xml +menge.exe -p ../examples/core/maze-navmesh.xml +menge.exe -p ../examples/core/maze-roadmap.xml +menge.exe -p ../examples/core/maze-vectorfield.xml +menge.exe -p ../examples/core/navMesh.xml +menge.exe -p ../examples/core/obstacleSwitch.xml +menge.exe -p ../examples/core/periodic.xml +menge.exe -p ../examples/core/persistGoal.xml +menge.exe -p ../examples/core/randomGoal.xml +menge.exe -p ../examples/core/sharedGoal.xml +menge.exe -p ../examples/core/soccer.xml +menge.exe -p ../examples/core/stadium.xml +menge.exe -p ../examples/core/swap.xml +menge.exe -p ../examples/core/event.xml + +menge.exe -p ../examples/plugin/propertyX.xml +menge.exe -p ../examples/plugin/terrain.xml +menge.exe -p ../examples/plugin/aircraft/load/loadBack.xml +menge.exe -p ../examples/plugin/aircraft/load/loadByZone.xml +menge.exe -p ../examples/plugin/aircraft/load/loadFront.xml +menge.exe -p ../examples/plugin/aircraft/load/loadRandom.xml +menge.exe -p ../examples/plugin/aircraft/unload/simpleUnload.xml -t 0.1 --subSteps 9 +menge.exe -p ../examples/plugin/aircraft/unload/waitingAgent.xml +menge.exe -p ../examples/plugin/formation.xml +menge.exe -p ../examples/plugin/denseFormation.xml +menge.exe -p ../examples/plugin/formationChange.xml +menge.exe -p ../examples/plugin/formationNavigation.xml +menge.exe -p ../examples/plugin/fundDiag.xml + +menge.exe -p ../examples/hold/timer.xml \ No newline at end of file diff --git a/projects/resources/win/libfreetype-6.dll b/projects/resources/win/libfreetype-6.dll new file mode 100644 index 00000000..19850b30 Binary files /dev/null and b/projects/resources/win/libfreetype-6.dll differ diff --git a/projects/resources/win/libjpeg-8.dll b/projects/resources/win/libjpeg-8.dll new file mode 100644 index 00000000..74285d25 Binary files /dev/null and b/projects/resources/win/libjpeg-8.dll differ diff --git a/projects/resources/win/libpng15-15.dll b/projects/resources/win/libpng15-15.dll new file mode 100644 index 00000000..a5854d5d Binary files /dev/null and b/projects/resources/win/libpng15-15.dll differ diff --git a/projects/resources/win/libtiff-5.dll b/projects/resources/win/libtiff-5.dll new file mode 100644 index 00000000..f449d750 Binary files /dev/null and b/projects/resources/win/libtiff-5.dll differ diff --git a/projects/resources/win/libwebp-2.dll b/projects/resources/win/libwebp-2.dll new file mode 100644 index 00000000..e89ac8bf Binary files /dev/null and b/projects/resources/win/libwebp-2.dll differ diff --git a/projects/resources/win/runExample.bat b/projects/resources/win/runExample.bat new file mode 100644 index 00000000..27ede13d --- /dev/null +++ b/projects/resources/win/runExample.bat @@ -0,0 +1 @@ +menge -s ..\examples\%1S.xml -b ..\examples\%1B.xml --view ..\examples\%1V.xml -m %2 -d 100 \ No newline at end of file diff --git a/projects/resources/win/zlib1.dll b/projects/resources/win/zlib1.dll new file mode 100644 index 00000000..0eeaa294 Binary files /dev/null and b/projects/resources/win/zlib1.dll differ diff --git a/projects/resources/winlib/SDL.lib b/projects/resources/winlib/SDL.lib new file mode 100644 index 00000000..993fd2ba Binary files /dev/null and b/projects/resources/winlib/SDL.lib differ diff --git a/projects/resources/winlib/SDL_image.lib b/projects/resources/winlib/SDL_image.lib new file mode 100644 index 00000000..ac1b4b3a Binary files /dev/null and b/projects/resources/winlib/SDL_image.lib differ diff --git a/projects/resources/winlib/SDL_ttf.lib b/projects/resources/winlib/SDL_ttf.lib new file mode 100644 index 00000000..3883adad Binary files /dev/null and b/projects/resources/winlib/SDL_ttf.lib differ diff --git a/projects/resources/winlib/SDLmain.lib b/projects/resources/winlib/SDLmain.lib new file mode 100644 index 00000000..e003361d Binary files /dev/null and b/projects/resources/winlib/SDLmain.lib differ diff --git a/projects/resources/winlib/libpng.lib b/projects/resources/winlib/libpng.lib new file mode 100644 index 00000000..d3c5bdfa Binary files /dev/null and b/projects/resources/winlib/libpng.lib differ diff --git a/projects/resources/winlib/zlib.lib b/projects/resources/winlib/zlib.lib new file mode 100644 index 00000000..c809ecb5 Binary files /dev/null and b/projects/resources/winlib/zlib.lib differ diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.cpp new file mode 100644 index 00000000..5bf81377 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.cpp @@ -0,0 +1,98 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentGenerators/AgentGenerator.h" +#include "Math/RandGenerator.h" +#include "Math/consts.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of AgentGeneratorException + ///////////////////////////////////////////////////////////////////// + + AgentGeneratorException AGENT_GENERATOR_EXCEPTION; + + ///////////////////////////////////////////////////////////////////// + // Implementation of AgentGenerator + ///////////////////////////////////////////////////////////////////// + + AgentGenerator::AgentGenerator(): Element(), _disp(0x0), _dir(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + AgentGenerator::~AgentGenerator() { + if ( _disp ) { + delete _disp; + delete _dir; + } + } + + ///////////////////////////////////////////////////////////////////// + + void AgentGenerator::setNoiseGenerator( FloatGenerator * gen ) { + if ( _disp ) delete _disp; + _disp = gen; + if ( !_dir ) { + // NOTE: This isn't perfect uniform probability + // The closed interval means that 0 degrees is SLIGHTLY + // more probably than any other direction (but the skew + // is considered negligible in practice). + _dir = new UniformFloatGenerator( 0.f, TWOPI ); + } + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 AgentGenerator::addNoise( const Vector2 & pos ) { + if ( _disp ) { + float disp = _disp->getValue(); + float dir = _dir->getValue(); + float x = cos( dir ) * disp; + float y = sin( dir ) * disp; + return pos + Vector2( x, y ); + } else { + return pos; + } + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.h b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.h new file mode 100644 index 00000000..2b5e97f3 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGenerator.h @@ -0,0 +1,166 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentGenerator.h + * @brief The definition of the agent generator element. + * Defines the intial numbers and positions of agents in the simulation. + */ +#ifndef __AGENT_GENERATOR_H__ +#define __AGENT_GENERATOR_H__ + +#include "mengeCommon.h" +#include "Element.h" + +namespace Menge { + + namespace Math { + class FloatGenerator; + } + + namespace Agents { + // forward declaration + class BaseAgent; + + /*! + * @brief Exception class for agent generator computation. + */ + class MENGE_API AgentGeneratorException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + AgentGeneratorException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AgentGeneratorException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal agent generator exception. + */ + class MENGE_API AgentGeneratorFatalException : public AgentGeneratorException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + AgentGeneratorFatalException() : MengeException(), AgentGeneratorException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AgentGeneratorFatalException( const std::string & s ): MengeException(s), AgentGeneratorException(), MengeFatalException() {} + }; + + /*! + * @brief The base class inital agent generation. + * + * This is an abstract class, primarily defining the agent generation abstraction. + * Essentially, the AgentGenerator produces a set of agent positions. Its + * properties should be sufficient to produce a count of agents with + * defined positions. + */ + class MENGE_API AgentGenerator : public Element { + public: + /*! + * @brief Constructor + */ + AgentGenerator(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~AgentGenerator(); + + public: + /*! + * @brief Reports the number of agents created. + * + * @returns The number of agents this generator creates. + */ + virtual size_t agentCount() = 0; + + /*! + * @brief Get the position of the ith agent. + * + * @param i The index of the requested agent. + * @returns The 2D position of the agent based on the generator's parameters. + * @throws AgentGeneratorException if the index, i, is invalid. + */ + virtual Vector2 agentPos( size_t i ) = 0; + + /*! + * @brief Sets the Generators noise generation. + * + * The AgentGenerator takse position of the float generator provided and + * will delete it up on its destruction. + * + * @param gen The generator. + */ + void setNoiseGenerator( Math::FloatGenerator * gen ); + + /*! + * @brief Perturbs the given point according to the given noise generator. + * + * @param pos The position to perturb. + * @returns The perturbed point. + */ + Vector2 addNoise( const Vector2 & pos ); + + protected: + /*! + * @brief The generator for displacement amount (defaults to zero). + */ + Math::FloatGenerator * _disp; + + /*! + * @brief The generator for angular displacement. + */ + Math::FloatGenerator * _dir; + }; + + } // namespace Agents +} // namespace Menge +#endif // __AGENT_GENERATOR_H__ diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.cpp new file mode 100644 index 00000000..66be4358 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.cpp @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentGeneratorDatabase.h" +#include "AgentGenerators/ExplicitAgentGenerator.h" +#include "AgentGenerators/RectGridGenerator.h" +#include "AgentGenerators/HexLatticeGenerator.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< Agents::AgentGeneratorFactory, Agents::AgentGenerator >::getElementName() { return "agent generator"; } + + template <> + void ElementDB< Agents::AgentGeneratorFactory, Agents::AgentGenerator >::addBuiltins() { + addFactory( new Agents::ExplicitGeneratorFactory() ); + addFactory( new Agents::RectGridGeneratorFactory() ); + addFactory( new Agents::HexLatticeGeneratorFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.h b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.h new file mode 100644 index 00000000..aee70b98 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorDatabase.h @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentGeneratorDatabase.h + * @brief Central database for querying available agent generator implementations. + * + * For agent generators to be used in simulation, they must register + * themselves into the AgentGeneratorDatabase. This is done via the PluginEngine. + */ + +#ifndef __AGENT_GENERATOR_DATABASE_H__ +#define __AGENT_GENERATOR_DATABASE_H__ + +#include "ElementDatabase.h" +#include "AgentGenerators/AgentGeneratorFactory.h" +#include "AgentGenerators/AgentGenerator.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered agent generator implementations. + */ + typedef ElementDB< AgentGeneratorFactory, AgentGenerator > AgentGeneratorDB; + + } // namespace Agents + + // Declarations of explicit specialization +#ifndef DOXYGEN_SHOULD_SKIP_THIS + template<> void ElementDB< Agents::AgentGeneratorFactory, Agents::AgentGenerator >::addBuiltins(); + + template<> std::string ElementDB< Agents::AgentGeneratorFactory, Agents::AgentGenerator >::getElementName(); +#endif // DOXYGEN_SHOULD_SKIP_THIS +} // namespace Menge + +#endif // __AGENT_GENERATOR_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.cpp new file mode 100644 index 00000000..577cbe2a --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentGeneratorFactory.h" +#include "tinyxml.h" +#include "Math/RandGenerator.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of AgentGeneratorFactory + ///////////////////////////////////////////////////////////////////// + + bool AgentGeneratorFactory::setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< AgentGenerator >::setFromXML( gen, node, behaveFldr ) ) return false; + + Math::FloatGenerator * fGen = createFloatGenerator( node, 1.f, "displace_" ); + if ( fGen ) { + gen->setNoiseGenerator( fGen ); + } else { + logger << Logger::WARN_MSG << "Agent generator on line " << node->Row() << " has no valid noise definition. No noise applied."; + } + + return true; + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.h b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.h new file mode 100644 index 00000000..bb35ff47 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/AgentGeneratorFactory.h @@ -0,0 +1,83 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentGeneratorFactory.h + * @brief The factory for parsing xml data and instantiating + * agent generator implementations. + */ + +#ifndef __AGENT_GENERATOR_FACTORY_H__ +#define __AGENT_GENERATOR_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "AgentGenerators/AgentGenerator.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief A class for parsing the xml description of an agent generator + * and instantiating particular instances. + */ + class MENGE_API AgentGeneratorFactory : public ElementFactory< AgentGenerator > { + protected: + /*! + * @brief Given a pointer to a Goal Selector instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Goal Selector's type. + * (i.e. GoalSelectorFactory::thisFactory has already been called and returned true.) + * If sub-classes of GoalSelectorFactory introduce *new* GoalSelector parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the goal selector whose attributes are to be set. + * @param node The XML node containing the goal attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + } // namespace Agents +} // namespace Menge +#endif // __AGENT_GENERATOR_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.cpp new file mode 100644 index 00000000..ad147c0f --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.cpp @@ -0,0 +1,120 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ExplicitAgentGenerator.h" +#include "tinyxml.h" +#include "Logger.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ExplicitGenerator + //////////////////////////////////////////////////////////////////////////// + + ExplicitGenerator::ExplicitGenerator() : AgentGenerator(), _positions() { + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 ExplicitGenerator::agentPos( size_t i ) { + if ( i >= _positions.size() ) { + throw AgentGeneratorFatalException("ExplicitGenerator trying to access an agent outside of the specified population"); + } + return _positions[ i ]; + } + + //////////////////////////////////////////////////////////////////////////// + + void ExplicitGenerator::addPosition( const Vector2 & p ) { + _positions.push_back( addNoise( p ) ); + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ExplicitGeneratorFactory + //////////////////////////////////////////////////////////////////////////// + + bool ExplicitGeneratorFactory::setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const { + ExplicitGenerator * eGen = dynamic_cast< ExplicitGenerator * >( gen ); + assert( eGen != 0x0 && "Trying to set attributes of an explicit agent generator component on an incompatible object" ); + + if ( ! AgentGeneratorFactory::setFromXML( eGen, node, specFldr ) ) return false; + + for( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "Agent" ) { + try { + Vector2 p = parseAgent( child ); + eGen->addPosition( p ); + } catch ( AgentGeneratorException ) { + return false; + } + } else { + logger << Logger::WARN_MSG << "Found an unexpected child tag in an AgentGroup on line " << node->Row() << ". Ignoring the tag: " << child->ValueStr() << "."; + } + } + + return true; + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 ExplicitGeneratorFactory::parseAgent( TiXmlElement * node ) const { + float x, y; + double dVal; + bool valid = true; + if (node->Attribute( "p_x", &dVal ) ) { + x = (float)dVal; + } else { + valid = false; + } + if (node->Attribute( "p_y", &dVal ) ) { + y = (float)dVal; + } else { + valid = false; + } + if ( ! valid ) { + logger << Logger::ERR_MSG << "Agent on line " << node->Row() << " didn't define position!"; + throw AgentGeneratorFatalException( "Agent in explicit generator didn't define a position" ); + } + return Vector2( x, y ); + } + + } // namespace Agents +} // namespace Menge + diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.h b/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.h new file mode 100644 index 00000000..a4c0147c --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/ExplicitAgentGenerator.h @@ -0,0 +1,169 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ExplicitAgentGenerator.h + * @brief An agent generator which creates a set of agents based on an explicit + * enumeration of agent positions. + */ + +#ifndef __EXPLICIT_AGENT_GENERATOR_H__ +#define __EXPLICIT_AGENT_GENERATOR_H__ + +#include "mengeCommon.h" +#include "AgentGenerators/AgentGenerator.h" +#include "AgentGenerators/AgentGeneratorFactory.h" +#include + +namespace Menge { + + namespace Agents { + /*! + * @brief Definition of agent generator class which produces agents based on + * explicit enumeration of agent positions in an XML file. + */ + class MENGE_API ExplicitGenerator : public AgentGenerator { + public: + /*! + * @brief Constructor + */ + ExplicitGenerator(); + + /*! + * @brief Reports the number of agents created. + * + * @returns The number of agents this generator creates. + */ + virtual size_t agentCount() { return _positions.size(); } + + /*! + * @brief Get the position of the ith agent. + * + * @param i The index of the requested agent. + * @returns The 2D position of the agent based on the generator's parameters. + * @throws AgentGeneratorException if the index, i, is invalid. + */ + virtual Vector2 agentPos( size_t i ); + + /*! + * @brief Adds a position to the generator + * + * @param p The position to add. + */ + void addPosition( const Vector2 & p ); + + protected: + /*! + * @brief The agent positions parsed from the file. + */ + std::vector< Vector2 > _positions; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for ExplicitGenerator + */ + class MENGE_API ExplicitGeneratorFactory : public AgentGeneratorFactory { + public: + /*! + * @brief The name of the generator type. + * + * The generator's name must be unique among all registered agent generator components. + * Each agent generator factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "explicit"; } + + /*! + * @brief A description of the agent generator. + * + * Each agent generator factory must override this function. + * + * @returns A string containing the agent generator description. + */ + virtual const char * description() const { + return "Agent generation is done via an explicit list of agent positions, given in the XML specification."; + }; + + protected: + /*! + * @brief Create an instance of this class's agent generator implementation. + * + * All AgentGeneratorFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding generator type. The various field values + * of the instance will be set in a subsequent call to AgentGeneratorFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EleAgentGenerator class. + */ + AgentGenerator * instance() const { return new ExplicitGenerator(); } + + /*! + * @brief Given a pointer to an AgentGenerator instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this AgentGenerator's type. + * (i.e. AgentGenerator::thisFactory has already been called and returned true.) + * If sub-classes of AgentGeneratorFactory introduce *new* AgentGenerator parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the agent generator whose attributes are to be set. + * @param node The XML node containing the agent generator attributes. + * @param specFldr The path to the specification file. If the AgentGenerator references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief Parses an agent position from an \ tag. + * + * @param node The XML node containing the agent definition. + * @returns The 2D point defined in the \ tag. + * @throws AgentGeneratorException is the agent tag doesn't provide the required data. + */ + Vector2 parseAgent( TiXmlElement * node ) const; + }; + } // namespace Agents +} // namespace Menge +#endif // __EXPLICIT_AGENT_GENERATOR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.cpp new file mode 100644 index 00000000..015dd496 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.cpp @@ -0,0 +1,242 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HexLatticeGenerator.h" +#include "tinyxml.h" +#include "Logger.h" +#include "Math/consts.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of Helper functions + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Computes the effective density of an agent to achieve the target + * density. + * + * @param density The target density. + * @returns The radius of the disk which, if maximally packed, achieves the + * target density. + */ + float effectiveRadius( float density ) { + return 1.f / sqrt( 2.f * density * sqrt( 3.f ) ); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Computes the rank distance based on a target radius. + * rank distance is the distance between two rows in the lattice. + * + * @param radius The target radius of the disk. + * @returns The distance between rows. + */ + float rankDistance( float radius ) { + return radius * sqrt( 3.f ); + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of HexLatticeGenerator + //////////////////////////////////////////////////////////////////////////// + + HexLatticeGenerator::HexLatticeGenerator() : AgentGenerator(), _anchor(0.f,0.f), _rowDir(ROW_X), + _cosRot(1.f), _sinRot(0.f), _totalPop(0), _rowDist(0.f), _nbrDist(0.f), _rowPop(0), + _rowCount(0) + { + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 HexLatticeGenerator::agentPos( size_t i ) { + if ( i >= _totalPop ) { + throw AgentGeneratorFatalException("HexLatticeGenerator trying to access an agent outside of the specified population"); + } + + // Compute local position + const float R = _nbrDist * 0.5f; + + float x, y; + if ( _rowDir == ROW_X ) { + const size_t BAND_POP = _rowPop * 2 - 1; + size_t band = i / BAND_POP; // number of full preceeding bands + i -= band * BAND_POP; + if ( i >= _rowPop ) { + // minor row + i -= _rowPop; + x = R + i * _nbrDist; + y = band * 2.f * _rowDist + _rowDist; + } else { + // major row + x = i * _nbrDist; + y = band * 2.f * _rowDist; + } + } else { + const size_t column = i / _rowPop; // number of full columns preceding i + i -= _rowPop * column; + x = column * _rowDist; + y = i * _nbrDist; + if ( column % 2 ) { + y += R; + } + } + Vector2 p = addNoise( Vector2( x, y ) ); + // rotated + Vector2 r = Vector2( _cosRot * p._x - _sinRot * p._y, + _cosRot * p._y + _sinRot * p._x ); + // world + return _anchor + r; + } + + //////////////////////////////////////////////////////////////////////////// + + void HexLatticeGenerator::setRotationDeg( float angle ) { + float rad = angle * DEG_TO_RAD; + _cosRot = cos( rad ); + _sinRot = sin( rad ); + } + + //////////////////////////////////////////////////////////////////////////// + + void HexLatticeGenerator::set( const Vector2 & anchor, AnchorAlignEnum align, LatticeRowEnum dir, + float width, float density, size_t tgtPopulation, float angle ) + { + _rowDir = dir; + setRotationDeg( angle ); + float r = effectiveRadius( density ); + _rowDist = rankDistance( r ); + _nbrDist = 2.f * r; + // Compute the layout of the agents for quick compute + float actualWidth; + switch ( dir ) { + case ROW_X: + _rowPop = (size_t)( width / _nbrDist ); + if ( _rowPop == 0 ) ++_rowPop; + _rowCount = ( tgtPopulation / ( 2 * _rowPop - 1 ) + 1 ) * 2; + _totalPop = ( 2 * _rowPop - 1 ) * ( _rowCount / 2 ); + if ( _totalPop - ( _rowPop - 1 ) > tgtPopulation ) { + _totalPop -= ( _rowPop - 1 ); + --_rowCount; + } + actualWidth = ( _rowPop - 1 ) * _nbrDist; + break; + case ROW_Y: + _rowCount = (int)( width / _rowDist ); + if ( _rowCount == 0 ) ++_rowCount; + _rowPop = tgtPopulation / _rowCount + 1; + _totalPop = _rowCount * _rowPop; + actualWidth = ( _rowCount - 1 ) * _rowDist; + break; + } + // Recompute _anchor based on _anchorAlign - essentially, change the anchor point + // such that the first agent is always placed at the origin. + // This is the rotated displacement of the center/right corner to the origin + if ( align == CENTER ) { + _anchor = anchor - Vector2( _cosRot * actualWidth, _sinRot * actualWidth ) * 0.5f; + } else if ( align == RIGHT_CORNER ) { + _anchor = anchor - Vector2( _cosRot * actualWidth, _sinRot * actualWidth ); + } else { + // Don't need any modification for _align == LEFT + _anchor = anchor; + } + + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of HexLatticeGeneratorFactory + //////////////////////////////////////////////////////////////////////////// + + HexLatticeGeneratorFactory::HexLatticeGeneratorFactory() : AgentGeneratorFactory() { + _anchorXID = _attrSet.addFloatAttribute( "anchor_x", true, 0.f ); + _anchorYID = _attrSet.addFloatAttribute( "anchor_y", true, 0.f ); + _alignID = _attrSet.addStringAttribute( "alignment", true, "center" ); + _rowDirID = _attrSet.addStringAttribute( "row_direction", true, "x" ); + _densityID = _attrSet.addFloatAttribute( "density", true, 0.f ); + _widthID = _attrSet.addFloatAttribute( "width", true, 0.f ); + _popID = _attrSet.addSizeTAttribute( "population", true, 0 ); + _rotID = _attrSet.addFloatAttribute( "rotation", false, 0.f ); + } + + //////////////////////////////////////////////////////////////////////////// + + bool HexLatticeGeneratorFactory::setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const { + HexLatticeGenerator * lGen = dynamic_cast< HexLatticeGenerator * >( gen ); + assert( lGen != 0x0 && "Trying to set attributes of a hexagonal lattice agent generator component on an incompatible object" ); + + if ( ! AgentGeneratorFactory::setFromXML( lGen, node, specFldr ) ) return false; + + HexLatticeGenerator::AnchorAlignEnum align; + std::string alignS = _attrSet.getString( _alignID ); + if ( alignS == "center" ) { + align = HexLatticeGenerator::CENTER; + } else if ( alignS == "left" ) { + align = HexLatticeGenerator::LEFT_CORNER; + } else if ( alignS == "right" ) { + align = HexLatticeGenerator::RIGHT_CORNER; + } else { + logger << Logger::ERR_MSG << "Incorrectly specified hex lattice alignment value on line " << node->Row() << ": " << alignS << ". Should be center, left, or right."; + return false; + } + + HexLatticeGenerator::LatticeRowEnum dir; + std::string rowDir = _attrSet.getString( _rowDirID ); + if ( rowDir == "x" ) { + dir = HexLatticeGenerator::ROW_X; + } else if ( rowDir == "y" ) { + dir = HexLatticeGenerator::ROW_Y; + } else { + logger << Logger::ERR_MSG << "Incorrectly specified hex lattice row direction value on line " << node->Row() << ": " << rowDir << ". Should be x or y."; + return false; + } + lGen->set( Vector2( _attrSet.getFloat( _anchorXID ), _attrSet.getFloat( _anchorYID ) ), + align, + dir, + _attrSet.getFloat( _widthID ), + _attrSet.getFloat( _densityID ), + _attrSet.getSizeT( _popID ), + _attrSet.getFloat( _rotID ) + ); + + return true; + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.h b/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.h new file mode 100644 index 00000000..a9a5d1d1 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/HexLatticeGenerator.h @@ -0,0 +1,297 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HexLatticeGenerator.h + * @brief An agent generator which creates a set of agents based on the definition + * of a hexagonal packed lattice fit into a rectangle. (i.e., rows are offset + * for maximal packing). + */ + +#ifndef __LATTICE_AGENT_GENERATOR_H__ +#define __LATTICE_AGENT_GENERATOR_H__ + +#include "mengeCommon.h" +#include "AgentGenerators/AgentGenerator.h" +#include "AgentGenerators/AgentGeneratorFactory.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief Definition of an agent generator class which produces agents based on + * the positions of intersections on a hexagonal lattice bounded by a + * rectangle. + * + * Circles can be maximally packed into a hexagonal lattice. In this case, an open + * rectangular region is defined (relative to an anchor point) and agents are placed + * in a hexagonal lattice, bounded by the rectangular region on three sides. + * + * The rectangular region is defined in "local" space. In its own local space, + * the rectangular region lies on the x-axis and extends into the positive y-direction. + * The "front" of the region lies on the x-axis and the left and right sides extend + * into the positive y-direction. The alignment of the rectangular region relative + * to the anchor point depends on the AnchorAlignEnum value. + * + * The hexagonal grid lattice size is based on the target average density. The lattice + * points are placed to achieve that average density. The lattice will either be aligned + * with the x-axis or the y-axis, depending on the LatticeRowEnum value. + */ + class MENGE_API HexLatticeGenerator : public AgentGenerator { + public: + /*! + * @brief Enumeration specifying arrangement relative to the anchor point. + */ + enum AnchorAlignEnum { + CENTER, ///< The front boundary is centered on the anchor + LEFT_CORNER, ///< The front boundary's "left" corner is on the anchor + RIGHT_CORNER ///< The front boundary's "right" corner is on the anchor + }; + + /*! + * @brief Enumeration indicating which axis the regular rows occur. + */ + enum LatticeRowEnum { + ROW_X, ///< The rows run parallel with the local x-axis + ROW_Y ///< The rows run parallel with the local y-axis + }; + + /*! + * @brief Constructor + */ + HexLatticeGenerator(); + + /*! + * @brief Reports the number of agents created. + * + * @returns The number of agents this generator creates. + */ + virtual size_t agentCount() { return _totalPop; } + + /*! + * @brief Get the position of the ith agent. + * + * @param i The index of the requested agent. + * @returns The 2D position of the agent based on the generator's parameters. + * @throws AgentGeneratorException if the index, i, is invalid. + */ + virtual Vector2 agentPos( size_t i ); + + /*! + * @brief Sets the properties of the generator + * + * @param anchor The anchor position of the lattice. + * @param align The target alignment. + * @param dir The desired row direction. + * @param width The width of the bounding region + * @param density The target density (agent /m^2). + * @param tgtPopulation The target population (agents). + * @param angle The rotation angle (in degrees). + */ + void set( const Vector2 & anchor, AnchorAlignEnum align, LatticeRowEnum dir, + float width, float density, size_t tgtPopulation, float angle ); + + /*! + * @brief Sets the lattice rotation. + * + */ + void setRotationDeg( float angle ); + + protected: + /*! + * @brief The anchor point of the lattice. One agent will be positioned + * at this world coordainte. + */ + Vector2 _anchor; + + /*! + * @brief The direction of the row layout. + */ + LatticeRowEnum _rowDir; + + /*! + * @brief The cosine of the amount the lattice is rotated around its anchor point. + * positive rotation values are counter-clockwise rotation. + */ + float _cosRot; + + /*! + * @brief The sine of the amount the lattice is rotated around its anchor point. + * positive rotation values are counter-clockwise rotation. + */ + float _sinRot; + + /*! + * @brief The actual number of agents to create based on run-time parameters. + * This value is only valid AFTER finalize has been called. + */ + size_t _totalPop; + + /*! + * @brief The distance between rows for the given target density. + */ + float _rowDist; + + /*! + * @brief The distance between neighbors in a single row for the given target + * density. + */ + float _nbrDist; + + /*! + * @brief The population of the major row (interpreted differently depending + * on lattice row direction. + */ + size_t _rowPop; + + /*! + * @brief The number of rows to create. + */ + size_t _rowCount; + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for HexLatticeGenerator + */ + class MENGE_API HexLatticeGeneratorFactory : public AgentGeneratorFactory { + public: + /*! + * @brief Constructor. + */ + HexLatticeGeneratorFactory(); + + /*! + * @brief The name of the generator type. + * + * The generator's name must be unique among all registered agent generator components. + * Each agent generator factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "hex_lattice"; } + + /*! + * @brief A description of the agent generator. + * + * Each agent generator factory must override this function. + * + * @returns A string containing the agent generator description. + */ + virtual const char * description() const { + return "Agent generation is done via the specification of a bounded hexagonal lattice."; + }; + + protected: + /*! + * @brief Create an instance of this class's agent generator implementation. + * + * All AgentGeneratorFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding generator type. The various field values + * of the instance will be set in a subsequent call to AgentGeneratorFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated AgentGenerator class. + */ + AgentGenerator * instance() const { return new HexLatticeGenerator(); } + + /*! + * @brief Given a pointer to an AgentGenerator instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this AgentGenerator's type. + * (i.e. AgentGenerator::thisFactory has already been called and returned true.) + * If sub-classes of AgentGeneratorFactory introduce *new* AgentGenerator parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the agent generator whose attributes are to be set. + * @param node The XML node containing the agent generator attributes. + * @param specFldr The path to the specification file. If the AgentGenerator references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "anchor_x" float parameter. + */ + size_t _anchorXID; + + /*! + * @brief The identifier for the "anchor_y" float parameter. + */ + size_t _anchorYID; + + /*! + * @brief The identifier for the "alignment" string parameter. + */ + size_t _alignID; + + /*! + * @brief The identifier for the "row_direction" string parameter. + */ + size_t _rowDirID; + + /*! + * @brief The identifier for the "density" float parameter. + */ + size_t _densityID; + + /*! + * @brief The identifier for the "width" float parameter. + */ + size_t _widthID; + + /*! + * @brief The identifier for the "count" size_t parameter. + */ + size_t _popID; + + /*! + * @brief The identifier for the "rotation" float parameter. + */ + size_t _rotID; + }; + } // namespace Agents +} // namespace Menge +#endif // __LATTICE_AGENT_GENERATOR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.cpp b/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.cpp new file mode 100644 index 00000000..0d76f1c1 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.cpp @@ -0,0 +1,116 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "RectGridGenerator.h" +#include "tinyxml.h" +#include "Logger.h" +#include "Math/consts.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of RectGridGenerator + //////////////////////////////////////////////////////////////////////////// + + RectGridGenerator::RectGridGenerator() : AgentGenerator(), _anchor(0.f,0.f), _offset(0.f,0.f), _xCount(0), _yCount(0), _cosRot(1.f), _sinRot(0.f) { + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 RectGridGenerator::agentPos( size_t i ) { + if ( i >= _xCount * _yCount ) { + throw AgentGeneratorFatalException("RectGridGenerator trying to access an agent outside of the specified population"); + } + size_t v = i / _xCount; + size_t u = i % _xCount; + // local + Vector2 p = addNoise( Vector2( u * _offset._x, v * _offset._y ) ); + // rotated + Vector2 r = Vector2( _cosRot * p._x - _sinRot * p._y, + _cosRot * p._y + _sinRot * p._x ); + // world + return _anchor + r; + } + + //////////////////////////////////////////////////////////////////////////// + + void RectGridGenerator::setRotationDeg( float angle ) { + float rad = angle * DEG_TO_RAD; + _cosRot = cos( rad ); + _sinRot = sin( rad ); + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of RectGridGeneratorFactory + //////////////////////////////////////////////////////////////////////////// + + RectGridGeneratorFactory::RectGridGeneratorFactory() : AgentGeneratorFactory() { + // name required default + _anchorXID = _attrSet.addFloatAttribute( "anchor_x", true, 0.f ); + _anchorYID = _attrSet.addFloatAttribute( "anchor_y", true, 0.f ); + _offsetXID = _attrSet.addFloatAttribute( "offset_x", true, 0.f ); + _offsetYID = _attrSet.addFloatAttribute( "offset_y", true, 0.f ); + _xCountID = _attrSet.addSizeTAttribute( "count_x", true, 0 ); + _yCountID = _attrSet.addSizeTAttribute( "count_y", true, 0 ); + _rotID = _attrSet.addFloatAttribute( "rotation", false, 0.f ); + + } + + //////////////////////////////////////////////////////////////////////////// + + bool RectGridGeneratorFactory::setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const { + RectGridGenerator * lGen = dynamic_cast< RectGridGenerator * >( gen ); + assert( lGen != 0x0 && "Trying to set attributes of a rectangular grid agent generator component on an incompatible object" ); + + if ( ! AgentGeneratorFactory::setFromXML( lGen, node, specFldr ) ) return false; + + lGen->setAnchor( Vector2( _attrSet.getFloat( _anchorXID ), + _attrSet.getFloat( _anchorYID ) ) ); + lGen->setOffset( Vector2( _attrSet.getFloat( _offsetXID ), + _attrSet.getFloat( _offsetYID ) ) ); + lGen->setAgentCounts( _attrSet.getSizeT( _xCountID ), + _attrSet.getSizeT( _yCountID ) ); + lGen->setRotationDeg( _attrSet.getFloat( _rotID ) ); + + return true; + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.h b/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.h new file mode 100644 index 00000000..3f32216b --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentGenerators/RectGridGenerator.h @@ -0,0 +1,267 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file RectGridGenerator.h + * @brief An agent generator which creates a set of agents based on the definition + * of a rectangular lattice, with an agent at each point. + */ + +#ifndef __RECT_GRID_GENERATOR_H__ +#define __RECT_GRID_GENERATOR_H__ + +#include "mengeCommon.h" +#include "AgentGenerators/AgentGenerator.h" +#include "AgentGenerators/AgentGeneratorFactory.h" +#include + +namespace Menge { + + namespace Agents { + /*! + * @brief Definition of an agent generator class which produces agents based on + * the positions of intersections on a lattice--one agent per intersection. + */ + class MENGE_API RectGridGenerator : public AgentGenerator { + public: + /*! + * @brief Constructor + */ + RectGridGenerator(); + + /*! + * @brief Reports the number of agents created. + * + * @returns The number of agents this generator creates. + */ + virtual size_t agentCount() { return _xCount * _yCount; } + + /*! + * @brief Get the position of the ith agent. + * + * @param i The index of the requested agent. + * @returns The 2D position of the agent based on the generator's parameters. + * @throws AgentGeneratorException if the index, i, is invalid. + */ + virtual Vector2 agentPos( size_t i ); + + /*! + * @brief Sets the anchor position. + * + * @param p The anchor position. + */ + void setAnchor( const Vector2 & p ) { _anchor.set( p ); } + + /*! + * @brief Sets the offset value. + * + * @param o The offset value. + */ + void setOffset( const Vector2 & o ) { _offset.set( o ); } + + /*! + * @brief Sets the number of agents in the local x-direction. + * + * @param count The count of agents. + */ + void setXCount( size_t count ) { _xCount = count; } + + /*! + * @brief Sets the number of agents in the local y-direction. + * + * @param count The count of agents. + */ + void setYCount( size_t count ) { _yCount = count; } + + /*! + * @brief Sets the number of agents in the local x- and y-directions. + * + * @param xCount The count of agents in the x-direction. + * @param yCount The count of agents in the y-direction. + */ + void setAgentCounts( size_t xCount, size_t yCount ) { _xCount = xCount; _yCount = yCount; } + + /*! + * @brief Sets the lattice rotation. + * + * @param angle The rotation angle (in degrees). + */ + void setRotationDeg( float angle ); + + protected: + /*! + * @brief The anchor point of the lattice. One agent will be positioned + * at this world coordainte. + */ + Vector2 _anchor; + + /*! + * @brief The offset from one agent to the next agent (along the local + * x- and y-axes, respectively. + */ + Vector2 _offset; + + /*! + * @brief The number of agents along the local x-axis. + */ + size_t _xCount; + + /*! + * @brief The number of agents along the local y-axis. + */ + size_t _yCount; + + /*! + * @brief The cosine of the amount the lattice is rotated around its anchor point. + * positive rotation values are counter-clockwise rotation. + */ + float _cosRot; + + /*! + * @brief The sine of the amount the lattice is rotated around its anchor point. + * positive rotation values are counter-clockwise rotation. + */ + float _sinRot; + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for RectGridGenerator + */ + class MENGE_API RectGridGeneratorFactory : public AgentGeneratorFactory { + public: + /*! + * @brief Constructor. + */ + RectGridGeneratorFactory(); + + /*! + * @brief The name of the generator type. + * + * The generator's name must be unique among all registered agent generator components. + * Each agent generator factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "rect_grid"; } + + /*! + * @brief A description of the agent generator. + * + * Each agent generator factory must override this function. + * + * @returns A string containing the agent generator description. + */ + virtual const char * description() const { + return "Agent generation is done via the specification of a rectangular grid."; + }; + + protected: + /*! + * @brief Create an instance of this class's agent generator implementation. + * + * All AgentGeneratorFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding generator type. The various field values + * of the instance will be set in a subsequent call to AgentGeneratorFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated AgentGenerator class. + */ + AgentGenerator * instance() const { return new RectGridGenerator(); } + + /*! + * @brief Given a pointer to an AgentGenerator instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this AgentGenerator's type. + * (i.e. AgentGenerator::thisFactory has already been called and returned true.) + * If sub-classes of AgentGeneratorFactory introduce *new* AgentGenerator parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the agent generator whose attributes are to be set. + * @param node The XML node containing the agent generator attributes. + * @param specFldr The path to the specification file. If the AgentGenerator references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( AgentGenerator * gen, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "anchor_x" float parameter. + */ + size_t _anchorXID; + + /*! + * @brief The identifier for the "anchor_y" float parameter. + */ + size_t _anchorYID; + + /*! + * @brief The identifier for the "offset_x" float parameter. + */ + size_t _offsetXID; + + /*! + * @brief The identifier for the "offset_y" float parameter. + */ + size_t _offsetYID; + + /*! + * @brief The identifier for the "count_x" size_t parameter. + */ + size_t _xCountID; + + /*! + * @brief The identifier for the "count_y" size_t parameter. + */ + size_t _yCountID; + + /*! + * @brief The identifier for the "rotation" float parameter. + */ + size_t _rotID; + }; + } // namespace Agents +} // namespace Menge + +#endif // __RECT_GRID_GENERATOR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentInitializer.cpp b/src/Menge/MengeCore/Agents/AgentInitializer.cpp new file mode 100644 index 00000000..f3769a12 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentInitializer.cpp @@ -0,0 +1,375 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentInitializer.h" +#include "BaseAgent.h" +#include "Math/RandGenerator.h" +#include "tinyxml.h" +#include "Utils.h" +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////// + // Implementation of AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float MAX_SPEED = 2.5f; ///< The default maximum speed + const float MAX_ACCEL = 2.f; ///< The default maximum acceleration. + const float PREF_SPEED = 1.34f; ///< The default preferred speed + const int MAX_NEIGHBORS = 10; ///< The default maximum number of neighbors + const float NEIGHBOR_DIST = 5.f; ///< The default neighbor distance + const float RADIUS = 0.2f; ///< The default radius + const size_t CLASS = 0; ///< The default class + const float PRIORITY = 0.f; ///< The default priority + const float MAX_ANGLE_VEL = TWOPI; ///< The default maximum angular velocity + const size_t OBSTACLE_SET = 0xFFFFFFFF; ///< The default obstacle set (all obstacles) + + //////////////////////////////////////////////////////////////// + + // TODO: Set this value with the VERBOSE flag in simple.exe + bool AgentInitializer::VERBOSE = false; + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() { + // Values for distribution + _maxSpeed = new ConstFloatGenerator( MAX_SPEED ); + _maxAccel = new ConstFloatGenerator( MAX_ACCEL ); + _prefSpeed = new ConstFloatGenerator( PREF_SPEED ); + _maxNeighbors = new ConstIntGenerator( MAX_NEIGHBORS ); + _neighborDist = new ConstFloatGenerator( NEIGHBOR_DIST ); + _radius = new ConstFloatGenerator( RADIUS ); + _maxAngVel = new ConstFloatGenerator( MAX_ANGLE_VEL ); + // single values + _obstacleSet = OBSTACLE_SET; + _priority = PRIORITY; + _class = CLASS; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) { + _maxSpeed = init._maxSpeed->copy(); + _maxAccel = init._maxAccel->copy(); + _prefSpeed = init._prefSpeed->copy(); + _maxNeighbors = init._maxNeighbors->copy(); + _neighborDist = init._neighborDist->copy(); + _radius = init._radius->copy(); + _maxAngVel = init._maxAngVel->copy(); + _obstacleSet = init._obstacleSet; + _priority = init._priority; + _class = init._class; + + std::vector< BFSM::VelModifier * >::const_iterator vItr = init._velModifiers.begin(); + for ( ; vItr != init._velModifiers.end(); ++vItr ) { + _velModifiers.push_back((*vItr)->copy()); + + } + + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _maxSpeed; + delete _maxAccel; + delete _prefSpeed; + delete _maxNeighbors; + delete _neighborDist; + delete _radius; + delete _maxAngVel; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _maxSpeed ) delete _maxSpeed; + if ( _maxAccel ) delete _maxAccel; + if ( _prefSpeed ) delete _prefSpeed; + if ( _maxNeighbors ) delete _maxNeighbors; + if ( _neighborDist ) delete _neighborDist; + if ( _radius ) delete _radius; + if ( _maxAngVel ) delete _maxAngVel; + + // Values for distribution + _maxSpeed = new ConstFloatGenerator( MAX_SPEED ); + _maxAccel = new ConstFloatGenerator( MAX_ACCEL ); + _prefSpeed = new ConstFloatGenerator( PREF_SPEED ); + _maxNeighbors = new ConstIntGenerator( MAX_NEIGHBORS ); + _neighborDist = new ConstFloatGenerator( NEIGHBOR_DIST ); + _radius = new ConstFloatGenerator( RADIUS ); + _maxAngVel = new ConstFloatGenerator( MAX_ANGLE_VEL ); + // single values + _priority = PRIORITY; + _obstacleSet = OBSTACLE_SET; + _class = CLASS; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::parseProperties( TiXmlElement * node, const std::string & sceneFldr) { + //first let's decide if this is a velocity modifier + if (node->ValueStr() == "VelModifier"){ + //this is, we need to find out if we can parse it + BFSM::VelModifier *vel = BFSM::parseVelModifier( node, sceneFldr); + if ( vel == 0x0 ) { + return false; + } else { + _velModifiers.push_back(vel); + } + } else if ( isRelevant( node->ValueStr() ) ) { + // Extract the attributes of the tag + TiXmlAttribute * attr; + for ( attr = node->FirstAttribute(); attr; attr = attr->Next() ) { + ParseResult result = setFromXMLAttribute( attr->Name(), attr->ValueStr() ); + if ( result == FAILURE ) { + return false; + } else if ( result == IGNORED ) { + logger << Logger::WARN_MSG << "Encountered an unexpected per-agent attribute (" << attr->Name() << ") on line " << attr->Row() << "."; + } + } + // Now look for advanced property specifications + TiXmlElement* child; + for( child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( ! parsePropertySpec( child ) ) { + + return false; + } + } + } + // Irrelevant nodes are, by definition, successful. + return true; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( BaseAgent * agent ) { + agent->_maxSpeed = _maxSpeed->getValue(); + agent->_maxAccel = _maxAccel->getValue(); + agent->_prefSpeed = _prefSpeed->getValue(); + agent->_maxNeighbors = _maxNeighbors->getValue(); + agent->_neighborDist = _neighborDist->getValue(); + agent->_radius = _radius->getValue(); + agent->_maxAngVel = _maxAngVel->getValue(); + agent->_obstacleSet = _obstacleSet; + agent->_priority = _priority; + agent->_class = _class; + + std::vector< BFSM::VelModifier * >::iterator vItr = _velModifiers.begin(); + for ( ; vItr != _velModifiers.end(); ++vItr ) { + BFSM::VelModifier *newVel = (*vItr)->copy(); + agent->addVelModifier(newVel); + newVel->registerAgent(agent); + } + return true; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return tagName == "Common"; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + ParseResult result = IGNORED; + + if ( paramName == "neighbor_dist" ) { + result = constFloatGenerator( _neighborDist, value ); + } else if ( paramName == "pref_speed" ) { + result = constFloatGenerator( _prefSpeed, value ); + } else if ( paramName == "max_speed" ) { + result = constFloatGenerator( _maxSpeed, value ); + } else if ( paramName == "max_accel" ) { + result = constFloatGenerator( _maxAccel, value ); + } else if ( paramName == "max_neighbors" ) { + result = constIntGenerator( _maxNeighbors, value ); + } else if ( paramName == "r" ) { + result = constFloatGenerator( _radius, value ); + } else if ( paramName == "max_angle_vel" ) { + result = constFloatGenerator( _maxAngVel, value, DEG_TO_RAD ); + } else if ( paramName == "obstacleSet" ) { + result = constSizet( _obstacleSet, value ); + } else if ( paramName == "class" ) { + result = constSizet( _class, value ); + } else if ( paramName == "priority" ) { + result = constFloat( _priority, value ); + } + + if ( result == FAILURE ) { + // Found an expected parameter name, but got a bad value. That is failure + logger << Logger::WARN_MSG << "Attribute " << paramName << " had an incorrectly formed value: " << value << ". Using default value."; + } + + return result; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::parsePropertySpec( TiXmlElement * node ) { + if ( node->ValueStr() == "Property" ) { + const char * cName = node->Attribute( "name" ); + if ( cName == 0x0 ) { + logger << Logger::ERR_MSG << "AgentSet Property tag specified on line " << node->Row() << " without a \"name\" attribute."; + return false; + } + ::std::string propName( cName ); + return processProperty( propName, node ) != FAILURE; + } else if ( VERBOSE ) { + logger << Logger::WARN_MSG << "Unexpected tag when looking for a property of an AgentSet parameter set: " << node->ValueStr() << "\n"; + TiXmlAttribute * attr; + for ( attr = node->FirstAttribute(); attr; attr = attr->Next() ) { + if ( setFromXMLAttribute( attr->Name(), attr->ValueStr() ) == FAILURE ) { + return false; + } + } + } + // Unexpected tags are ignored + return true; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + ParseResult result = IGNORED; + if ( propName == "neighbor_dist" ) { + result = getFloatGenerator( _neighborDist, node ); + } else if ( propName == "pref_speed" ) { + result = getFloatGenerator( _prefSpeed, node ); + } else if ( propName == "max_speed" ) { + result = getFloatGenerator( _maxSpeed, node ); + } else if ( propName == "max_accel" ) { + result = getFloatGenerator( _maxAccel, node ); + } else if ( propName == "max_neighbors" ) { + result = getIntGenerator( _maxNeighbors, node ); + } else if ( propName == "r" ) { + result = getFloatGenerator( _radius, node ); + } else if ( propName == "max_angle_vel" ) { + result = getFloatGenerator( _maxAngVel, node, DEG_TO_RAD ); + } + if ( result == FAILURE ) { + logger << Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + logger << Logger::WARN_MSG << "AgentSet Property had unexpected name: " << propName << ". Ignored.\n"; + } + return result; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::constFloatGenerator( FloatGenerator * & gen, const ::std::string & valueStr, float scale ) { + try { + float f = toFloat( valueStr ); + if ( gen ) delete gen; + gen = new ConstFloatGenerator( f * scale ); + return ACCEPTED; + } catch ( UtilException ) { + return FAILURE; + } + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::constFloat( float & numValue, const ::std::string & valueStr, float scale ) { + try { + float f = toFloat( valueStr ); + numValue = f * scale; + return ACCEPTED; + } catch ( UtilException ) { + return FAILURE; + } + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::constIntGenerator( IntGenerator * & gen, const ::std::string & valueStr ) { + try { + int i = toInt( valueStr ); + if ( gen ) delete gen; + gen = new ConstIntGenerator( i ); + return ACCEPTED; + } catch ( UtilException ) { + return FAILURE; + } + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::constSizet( size_t & numValue, const ::std::string & valueStr ) { + try { + size_t i = toSize_t( valueStr ); + numValue = i; + return ACCEPTED; + } catch ( UtilException ) { + return FAILURE; + } + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::getFloatGenerator( FloatGenerator * & gen, TiXmlElement * node, float scale ) { + FloatGenerator * newGen = createFloatGenerator( node, scale ); + if ( newGen ) { + if ( gen ) delete gen; + gen = newGen; + return ACCEPTED; + } else { + return FAILURE; + } + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::getIntGenerator( IntGenerator * & gen, TiXmlElement * node ) { + IntGenerator * newGen = createIntGenerator( node ); + if ( newGen ) { + if ( gen ) delete gen; + gen = newGen; + return ACCEPTED; + } else { + return FAILURE; + } + } + } // namepsace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentInitializer.h b/src/Menge/MengeCore/Agents/AgentInitializer.h new file mode 100644 index 00000000..f3c5707d --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentInitializer.h @@ -0,0 +1,420 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentInitializer.h + * @brief The infrastructure for initializing agent properties + * from the scene specification file. + */ + +#ifndef __AGENT_INITIALIZER_H__ +#define __AGENT_INITIALIZER_H__ + +#include "CoreConfig.h" +#include +#include "VelocityModifiers/VelModifier.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + // Forward declarations + namespace Math { + class FloatGenerator; + class IntGenerator; + } + + using namespace Math; + + namespace Agents { + // forward declaration + class BaseAgent; + + /*! + * @brief Class which determines the agent properties for each new agent. + * + * This base agent intializer class facilitates setting all BaseAgent properties. + * The property values are set using number generators (see RandGenerator.h). + */ + class MENGE_API AgentInitializer { + public: + /*! + * @brief Return type for parsing efforts. Helps the various derived classes + * coordinate their work. + */ + enum ParseResult { + FAILURE = 0, ///< The parsing ended in failure. + IGNORED, ///< The XML data was ignored by the function. + ACCEPTED ///< The XML data was accepted by the function. + }; + + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The AgentInitializer to copy all values + * from. + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Parses an AgentSet property tag, setting agent values as + * appropriate. + * + * This function can be called on *all* AgentSet property tags. The function + * is responsible for determining which tags have relevant information and which + * are to be ignored. + * + * If a tag is deemed to be relevant, but the content of the tag is incorrect, + * such as a mal-formed property definition, then the parsing "fails". However, + * unexpected property attributes or specifications will be ignored. + * If the system is running in verbose mode, these unexpected attributes will be + * indicated on the console. + * + * Such a tag could look like this: + + * + + * or + + * + * + * + * + * + * @param node The xml node containing agent properties for an AgentSet. + * @param sceneFldr Since we now need access to resources at this stage, + * we pass the base folder for resource loading + * @returns True if parsing was "successful", false otherwise. + */ + bool parseProperties( TiXmlElement * node, const std::string & sceneFldr ); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties and then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + /*! + * @brief Determines if the agent properties parsing process will be verbose. + */ + static bool VERBOSE; + + protected: + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `` + * parameter set. + * + * @param tagName The name of the tag to test. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Parses the Property tag that is the child of an AgentSet Parameter + * tag. + * + * As with the other parsing code, success is defined by finding an expected, + * correct field *or* an unexpected tag (which is just ignored). Failure occurs + * when the tags are as expected, but the values are invalid. + * + * @param node The xml node containing agent properties for an AgentSet. + * @returns True if parsing was "successful", false otherwise. + */ + bool parsePropertySpec( TiXmlElement * node ); + + /*! + * @brief Process the given `` tag. + * + * As a pre-condition to this function, the XML node contains a `` + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extracted "name" attribute from the Property tag. + * @param node The XML node for the Property tag. + * @returns The ParseResult indicating if the property was successful + * (IGNORED or ACCEPTED) or if it was a malformed tag (FAILURE). + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief Helper function for setting a property from an xml attribute. + * + * This is used to parse and create a value generator in the case where the + * attribute is defined on the main property tag: e.g., + * + * + * + * @param numValue The new float will be put into this variable. + * @param valueStr The string representing the attribute value to convert + * to a const float generator. + * @param scale Optional argument for changing the units of the input value. + * (e.g., specification commonly describes angles as degrees, + * but internal representation is in radians). + * @returns A parse result indicating either ACCEPTED or FAILURE. IGNORED should + * never be a result, because it should only be called on expected + * parameters, so it must either succed or fail. + */ + ParseResult constFloat( float & numValue, const ::std::string & valueStr, float scale=1.f ); + + /*! + * @brief Helper function for setting a property from an xml attribute. + * + * This is used to parse and create a value generator in the case where the + * attribute is defined on the main property tag: e.g., + * + * + * + * @param numValue The new size_t will be put into this variable. + * @param valueStr The string representing the attribute value to convert + * to a const float generator. + * @returns A parse result indicating either ACCEPTED or FAILURE. IGNORED should + * never be a result, because it should only be called on expected + * parameters, so it must either succed or fail. + */ + ParseResult constSizet( size_t & numValue, const ::std::string & valueStr ); + + /*! + * @brief Helper function for setting a property from an xml Property node. + * + * This is used to parse and create a value generator in the case where the + * attribute is defined explicitly as a distribution on a Property tag, e.g., + * + * + * + * + * @param gen A reference to a pointer to a valid FloatGenerator. + * The new float generator will be put into this variable. + * @param node The xml node containing attributes for the distribution + * specification. + * @param scale Optional argument for changing the units of the input value. + * (e.g., specification commonly describes angles as degrees, + * but internal representation is in radians). + * @returns A parse result indicating either ACCEPTED or FAILURE. IGNORED should + * never be a result, because it should only be called on expected + * parameters, so it must either succed or fail. + */ + ParseResult getFloatGenerator( FloatGenerator * & gen, TiXmlElement * node, float scale=1.f ); + + /*! + * @brief Helper function for setting a property from an xml Property node. + * + * This is used to parse and create a value generator in the case where the + * attribute is defined on the main property tag: e.g., + * + * _id ] = agent->_maxSpeed; + agent->_maxSpeed = newValue( agent->_maxSpeed, agent->_id ); + break; + case BFSM::MAX_ACCEL: + _originalMap[ agent->_id ] = agent->_maxAccel; + agent->_maxAccel = newValue( agent->_maxAccel, agent->_id ); + break; + case BFSM::PREF_SPEED: + _originalMap[ agent->_id ] = agent->_prefSpeed; + agent->_prefSpeed = newValue( agent->_prefSpeed, agent->_id ); + break; + case BFSM::MAX_ANGLE_VEL: + _originalMap[ agent->_id ] = agent->_maxAngVel; + agent->_maxAngVel = newValue( agent->_maxAngVel, agent->_id ); + break; + case BFSM::NEIGHBOR_DIST: + _originalMap[ agent->_id ] = agent->_neighborDist; + agent->_neighborDist = newValue( agent->_neighborDist, agent->_id ); + break; + case BFSM::PRIORITY: + _originalMap[ agent->_id ] = agent->_priority; + agent->_priority = newValue( agent->_priority, agent->_id ); + break; + case BFSM::RADIUS: + _originalMap[ agent->_id ] = agent->_radius; + agent->_radius = newValue( agent->_radius, agent->_id ); + break; + } + _lock.release(); + } + + ///////////////////////////////////////////////////////////////////// + + void AgentPropertyManipulator::restore( Agents::BaseAgent * agent ) { + _lock.lock(); + std::map< size_t, float >::iterator itr = _originalMap.find( agent->_id ); + if ( itr == _originalMap.end() ) { + _lock.release(); + return; + } + float value = itr->second; + _originalMap.erase( itr ); + _lock.release(); + switch ( _property ) { + case BFSM::MAX_SPEED: + agent->_maxSpeed = value; + break; + case BFSM::MAX_ACCEL: + agent->_maxAccel = value; + break; + case BFSM::PREF_SPEED: + agent->_prefSpeed = value; + break; + case BFSM::MAX_ANGLE_VEL: + agent->_maxAngVel = value; + break; + case BFSM::NEIGHBOR_DIST: + agent->_neighborDist = value; + break; + case BFSM::PRIORITY: + agent->_priority = value; + break; + case BFSM::RADIUS: + agent->_radius = value; + break; + } + } + + ///////////////////////////////////////////////////////////////////// + + void AgentPropertyManipulator::setGenerator( FloatGenerator * gen ) { + if ( _operandGen ) delete _operandGen; // see note in destructor + _operandGen = gen; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SetPropertyManipulator + ///////////////////////////////////////////////////////////////////// + + float SetPropertyManipulator::newValue( float value, size_t agentID ) { + return _operandGen->getValue(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of OffsetPropertyManipulator + ///////////////////////////////////////////////////////////////////// + + float OffsetPropertyManipulator::newValue( float value, size_t agentID ) { + return value + _operandGen->getValue(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ScalePropertyManipulator + ///////////////////////////////////////////////////////////////////// + + float ScalePropertyManipulator::newValue( float value, size_t agentID ) { + return value * _operandGen->getValue(); + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/AgentPropertyManipulator.h b/src/Menge/MengeCore/Agents/AgentPropertyManipulator.h new file mode 100644 index 00000000..57a60231 --- /dev/null +++ b/src/Menge/MengeCore/Agents/AgentPropertyManipulator.h @@ -0,0 +1,221 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentPropertyManipulator.h + * @brief Classes for manipulating agent properties in an + * "undoable" manner (albeit, to a limited degree). + */ + +#ifndef __AGENT_PROPERTY_MANIPULATOR_H__ +#define __AGENT_PROPERTY_MANIPULATOR_H__ + +#include "Element.h" +#include "mengeCommon.h" +#include "FSMEnumeration.h" +#include +#include "SimpleLock.h" + + +namespace Menge { + // Forward declarations + namespace Agents { + class BaseAgent; + } + + + /*! + * @brief Helper function for parsing property actions + * + * It converts the xml string indicating the property to an + * enumerated value + * + * @param opName The name of the operand as specified in the + * xml specification. + * @returns The corresponding enumeration. If there is no corresponding + * enumeration, NO_PROPERTY is returned. + */ + MENGE_API BFSM::PropertyOperand parsePropertyName( const std::string & opName ); + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Base class for manipulating agent properties in an + * undoable manner. + * The undo is limited, it only maintains knowledge of one manipulation. + * If multiple manipulations are applied, only the last can be undone. + */ + class MENGE_API AgentPropertyManipulator : public Element { + public: + /*! + * @brief Constructor. + */ + AgentPropertyManipulator(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~AgentPropertyManipulator(); + + public: + /*! + * @brief Applies the manipulation to the given agent, storing + * the previous state for restoration. + * + * @param agent The agent to manipulate. + */ + void manipulate( Agents::BaseAgent * agent ); + + /*! + * @brief Restores the agent's previous value. + * + * If there is no previous value for the provided agent, nothing + * happens. + * + * @param agent The agent whose property value should be restored. + */ + void restore( Agents::BaseAgent * agent ); + + /*! + * @brief Sets the generator for the manipulator. + * + * @param gen The generator to assign to this manipulator. + * Any previous generator will be destroyed and + * it is assumed that the generator is *not* shared + * with any other entity. + */ + void setGenerator( FloatGenerator * gen ); + + /*! + * @brief Sets the property operand. + * + * @param prop The property to operate on. + */ + void setProperty( BFSM::PropertyOperand prop ) { _property = prop; } + + protected: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original value of the property. + * @param agentID The identifier for the agent. + * @returns The new value. + */ + virtual float newValue( float value, size_t agentID ) = 0; + + /*! + * @brief The generator for determining the operand value. + */ + FloatGenerator * _operandGen; + + /*! + * @brief The property to operate on. + */ + BFSM::PropertyOperand _property; + + /*! + * @brief A mapping from agent id to the agent's property + * value before the action was applied. + */ + std::map< size_t, float > _originalMap; + + /*! + * @brief Lock for guaranteeing thread-safety. + */ + SimpleLock _lock; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies a particular agent property based by explicitly + * setting the property value from a distribution. + */ + class MENGE_API SetPropertyManipulator : public AgentPropertyManipulator { + protected: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original value of the property. + * @param agentID The identifier for the agent. + * @returns The new value. + */ + virtual float newValue( float value, size_t agentID ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies a particular agent property based by adding + * the value from a distribution to the original agent + * parameter value. + */ + class MENGE_API OffsetPropertyManipulator : public AgentPropertyManipulator { + protected: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original value of the property. + * @param agentID The identifier for the agent. + * @returns The new value. + */ + virtual float newValue( float value, size_t agentID ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies a particular agent property based by multiplying + * the value from a distribution to the original agent + * parameter value. + */ + class MENGE_API ScalePropertyManipulator : public AgentPropertyManipulator { + protected: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original value of the property. + * @param agentID The identifier for the agent. + * @returns The new value. + */ + virtual float newValue( float value, size_t agentID ); + }; + +} // namespace Menge +#endif // __AGENT_PROPERTY_MANIPULATOR_H__ diff --git a/src/Menge/MengeCore/Agents/BaseAgent.cpp b/src/Menge/MengeCore/Agents/BaseAgent.cpp new file mode 100644 index 00000000..005066c8 --- /dev/null +++ b/src/Menge/MengeCore/Agents/BaseAgent.cpp @@ -0,0 +1,216 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "BaseAgent.h" +#include "Obstacle.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////// + // Implementation of BaseAgent + //////////////////////////////////////////////////////////////// + + BaseAgent::BaseAgent() { + _maxSpeed = 2.5f; + _maxAccel = 2.f; + _prefSpeed = 1.34f; + _pos = Vector2( 0.f, 0.f ); + _vel = Vector2( 0.f, 0.f ); + _velPref = PrefVelocity( Vector2(1.f,0.f), _prefSpeed, Vector2(0.f,0.f) ); + _velNew = Vector2( 0.f, 0.f ); + _orient = Vector2( 1.f, 0.f ); + _maxAngVel = TWOPI; // 360 degrees/sec + _maxNeighbors = 10; + _neighborDist = 5.f; + _nearAgents.clear(); + _nearObstacles.clear(); + _class = 0; + _obstacleSet = 0xFFFFFFFF; + _priority = 0.f; + _id = 0; + _radius = 0.19f; + } + + //////////////////////////////////////////////////////////////// + + void BaseAgent::initialize() { + _orient = _velPref.getPreferred(); + } + + //////////////////////////////////////////////////////////////// + + void BaseAgent::update( float timeStep ) { + float delV = abs( _vel - _velNew ); + //Check to see if new velocity violates acceleration constraints... + // TODO: Make the acceleration constraint respect collisions (particularly with + // obstacles. I.e. confirm that the new velocity STILL won't collide + // with the neighboring obstacles. + // The slick way to do this is to replace the float in the _nearObstacles to + // represent the minimum acceleration required to avoid collision with the + // obstacle in the next time step. Then I can simply take the larger of the + /// user-define max acceleration and the smallest required acceleration + if ( delV > _maxAccel * timeStep ) { + float w = _maxAccel * timeStep / delV; + _vel = (1.f - w ) * _vel + w * _velNew; + } else { + _vel = _velNew; + } + _pos += _vel * timeStep; + + float speedSq = absSq( _vel ); + if ( speedSq > 0.00001f ) { + float speed = sqrt( speedSq ); + Vector2 newOrient = _vel / speed; + + const float MAX_ANGLE_CHANGE = timeStep * _maxAngVel; + float maxCt = cos( MAX_ANGLE_CHANGE ); + float ct = newOrient * _orient; + if ( ct < maxCt ) { + // changing direction at a rate greater than _maxAngVel + float maxSt = sin( MAX_ANGLE_CHANGE ); + if ( det( _orient, newOrient ) > 0.f ) { + // rotate _orient left + _orient.set( maxCt * _orient._x - maxSt * _orient._y, maxSt * _orient._x + maxCt * _orient._y ); + } else { + // rotate _orient right + _orient.set( maxCt * _orient._x + maxSt * _orient._y, -maxSt * _orient._x + maxCt * _orient._y ); + } + } else { + _orient.set( newOrient ); + } + } + } + + //////////////////////////////////////////////////////////////// + + void BaseAgent::setPreferredVelocity(PrefVelocity &velocity) { + std::vector< BFSM::VelModifier * >::iterator vItr = _velModifiers.begin(); + for ( ; vItr != _velModifiers.end(); ++vItr ) { + (*vItr)->adaptPrefVelocity(this, velocity); + } + + //set my velocity to be the given one + _velPref = velocity; + } + + //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////// + + void BaseAgent::computeNewVelocity() { + throw AgentImplementationException(); + } + + //////////////////////////////////////////////////////////////// + + void BaseAgent::insertAgentNeighbor(const BaseAgent* agent, float distSq) { + if (this != agent) { + if (_nearAgents.size() != _maxNeighbors || distSq <= getMaxAgentRange()) { + if (_nearAgents.size() != _maxNeighbors) { + _nearAgents.push_back(NearAgent(distSq, agent)); + } + size_t i = _nearAgents.size() - 1; + while (i != 0 && distSq < _nearAgents[i-1].distanceSquared) { + _nearAgents[i] = _nearAgents[i-1]; + --i; + } + _nearAgents[i] = NearAgent(distSq, agent); + + } + } + } + + //////////////////////////////////////////////////////////////// + + void BaseAgent::insertObstacleNeighbor( const Obstacle* obstacle, float distSq ) { + // the assumption is that two obstacle neighbors MUST have the same classID + if ( obstacle->_class & _obstacleSet ) { + + if ( distSq < _neighborDist * _neighborDist) { + + _nearObstacles.push_back( NearObstacle(distSq, obstacle) ); + + size_t i = _nearObstacles.size() - 1; + while ( i != 0 && distSq < _nearObstacles[i-1].distanceSquared ) { + _nearObstacles[i] = _nearObstacles[i-1]; + --i; + } + _nearObstacles[i] = NearObstacle( distSq, obstacle ); + } + } + } + + /////////////////////////////////////////////////////////// + void BaseAgent::addVelModifier( BFSM::VelModifier * v ) { _velModifiers.push_back( v ); } + + /////////////////////////////////////////////////////////// + + void BaseAgent::startQuery(){ + _nearAgents.clear(); + _nearObstacles.clear(); + }; + + /////////////////////////////////////////////////////////// + + void BaseAgent::filterAgent(const BaseAgent *agent, float distance) { + insertAgentNeighbor(agent, distance); + }; + + /////////////////////////////////////////////////////////// + + void BaseAgent::filterObstacle(const Obstacle * obstacle, float distance){ + insertObstacleNeighbor(obstacle, distance); + }; + + /////////////////////////////////////////////////////////// + + float BaseAgent::getMaxAgentRange() { + if (_nearAgents.size() == _maxNeighbors){ + + return _nearAgents.back().distanceSquared; + + } + + return _neighborDist * _neighborDist; + } + + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/BaseAgent.h b/src/Menge/MengeCore/Agents/BaseAgent.h new file mode 100644 index 00000000..48645190 --- /dev/null +++ b/src/Menge/MengeCore/Agents/BaseAgent.h @@ -0,0 +1,403 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __BASE_AGENT_H__ +#define __BASE_AGENT_H__ + +/*! + * @file BaseAgent.h + * @brief Contains the BaseAgent class - the underlying class which + * defines the basic functionality for all shared agents. + */ + +// UTILS +#include "mengeCommon.h" +#include "XMLSimulatorBase.h" +#include "PrefVelocity.h" +#include "VelocityModifiers/VelModifier.h" +#include "SpatialQueries/ProximityQuery.h" +#include "SpatialQueries/SpatialQueryStructs.h" +// STL +#include +#include + +namespace Menge { + + namespace Agents { + + class Obstacle; + + /*! + * @brief Exception for BaseAgent problems. + */ + class MENGE_API AgentException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + AgentException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AgentException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal agent exception. + */ + class MENGE_API AgentFatalException : public AgentException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + AgentFatalException() : MengeException(), AgentException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AgentFatalException( const std::string & s ): MengeException(s), AgentException(), MengeFatalException() {} + }; + + /*! + * @brief Special agent exception - used for non-implemented functionality. + */ + class MENGE_API AgentImplementationException : public AgentFatalException { + public: + /*! + * @brief Default constructor. + */ + AgentImplementationException() : AgentFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AgentImplementationException( const std::string & s ): AgentFatalException(s) {} + }; + + /*! + * @brief Defines the basic agent properties and functionality that + * all simulation agents share. + */ + class MENGE_API BaseAgent : public ProximityQuery { + public: + + /*! + * @brief Default constructor. + */ + BaseAgent(); + + /*! + * @brief Initializes the agent + */ + void initialize(); + + /*! + * @brief Updates the two-dimensional position and two-dimensional + * velocity of this agent. + * + * @param timeStep The time step that will be taken. + */ + void update( float timeStep ); + + /*! + * @brief Given preferred velocity and neighboring agents and obstacles + * compute a new velocity. + * + * This should be overriden by child classes to give unique behaviors. + * Each pedestrian model is uniquely defined by how it computes its new + * velocity and this is the critical class. + * + * Trying to instantiate a BaseAgent will cause an exception to be thrown + * when calling this function. + */ + void computeNewVelocity(); + + /*! + * @brief Returns a pointer to the neighbor with given index + * + * @param idx The index of the desired agent. This index is *not* validated. + * @returns Pointer to the neighboring agent. + */ + const BaseAgent * getNeighbor( int idx ) const { return _nearAgents[ idx ].agent; } + + /*! + * @brief Returns a pointer to the obstacle with given index + * + * @param idx The index of the desired obstacle. This index is *not* validated. + * @returns Pointer to the nearby obstacle. + */ + const Obstacle * getObstacle( int idx ) const { return _nearObstacles[ idx ].obstacle; } + + + /*! + * @brief set the agents preferred velocity to the input velocity. + * + * @param velocity to be applied to the agent. + */ + void setPreferredVelocity(PrefVelocity &velocity); + + /*! + * @brief Add an velocity modifier to the agent + * + * @param v The modifier to add + */ + void addVelModifier( BFSM::VelModifier * v ); + + + // Properties of a basic agent + /*! + * @brief The maximum speed the agent can take. + */ + float _maxSpeed; + + /*! + * @brief The maximum acceleration the agent can experience (interpreted isotropically). + */ + float _maxAccel; + + /*! + * @brief The preferred speed of the agent + */ + float _prefSpeed; + + /*! + * @brief The current 2D position of the agent + */ + Vector2 _pos; + + /*! + * @brief The current 2D velocity of the agent + */ + Vector2 _vel; + + /*! + * @brief The 2D preferred velocity of the agent + */ + PrefVelocity _velPref; + + /*! + * @brief The new velocity computed in computeNewVelocity. + * + * This exists to allow the agents to be updated + * in parallel while preserving order-of-evaluation independence. + */ + Vector2 _velNew; + + /*! + * @brief The orientation vector (the direction the agent is facing which is not + * necessarily the same direction as the instantaneous velocity. + * + * Not all pedestrian models require orientation in their calculation of a new + * velocity. However, by introducing the property here, we accomplish two things: + * - All agents which *do* require orientation can update their orientation + * in a common mechanism, making comparisons them less dependent on differences + * in orientation computation and focusing on differences in the new velocity + * computation. + * - Second, it provides orientation information to the output trajectories for + * later visualization. + */ + Vector2 _orient; + + /*! + * @brief The agent's maximum angular velocity (in radians/sec) -- + * used for controlling the changes in agent orientation. + */ + float _maxAngVel; + + /*! + * @brief The number of nearby agents used to plan dynamic respones. + */ + size_t _maxNeighbors; + + /*! + * @brief The maximum distance at which another agent will be + * considered for a response. + */ + float _neighborDist; + + + /*! + * @brief The population class for this agent. + * + * Used to define behavior and visualization properties. + */ + size_t _class; + + /*! + * @brief A mask indicating the obstacles with compatible ids which + * this agent can see. + * + * This is a bitwise mask such that if + * the ith bit is 1, obstacles with id 2^i are visible. + */ + size_t _obstacleSet; + + /*! + * @brief The priority of each agent. + * + * The relative priority of agents determines aspects of their interaction behavior. + */ + float _priority; + + /*! + * @brief A globally unique identifier for each agent. + */ + size_t _id; + + /*! + * @brief The agent's radius. + * + * If the agent is represented as a circle, then this is simply + * the circle's radius. If the agent is represented as an ellipse, + * then this is the radius perpendicular to the orientation. + * Other geometries should provide their own interpretation. + * + * At a minimum, it is used to determine sideways clearance. + */ + float _radius; + + /*! + * @brief a set of velocity modifiers to be set with the agent. Allows for intermediate velocity changes + * + */ + std::vector _velModifiers; + + /*! + * @brief The nearby agents to which the agent should respond. + * + * Each pair consists of distance between the agent positions, squared + * and the pointer to the neigboring agent. + */ + std::vector _nearAgents; + + /*! + * @brief The nearby obstacles to which the agent should respond. + * + * Each pair consists of distance between agent position and wall, squared + * and the pointer to the wall. + */ + std::vector _nearObstacles; + + /*! + * @brief Inserts an agent neighbor into the set of neighbors of + * this agent. + * + * @param agent A pointer to the agent to be inserted. + * @param distSq the distance to the indicated agent + */ + void insertAgentNeighbor(const BaseAgent* agent, float distSq); + + /*! + * @brief Inserts a static obstacle neighbor into the set of neighbors + * of this agent. + * + * @param obstacle a pointer to the obstacle to be inserted + * @param distSq the distance to the indicated obstacle + */ + void insertObstacleNeighbor(const Obstacle* obstacle, float distSq); + + // TODO: Ultimately, this should go into an intention filter and not the agent itself + /*! + * @brief Sets the density sensitivity parameters. + * + * @param stride The stride factor. The physical component capturing height + * and the physicl relationship between speed and stride length. + * @param buffer The stride buffer. The psychological buffer required beyond + * that needed for stride length. + */ + virtual void setStrideParameters( float stride, float buffer ) {} + + + // Methods needed for a spatial query filter to work + + /*! + * @brief clears the result vectors. Resets the filter + */ + virtual void startQuery(); + + /*! + * @brief filters an agent and determines if it needs to be in the near set + * + * @param agent the agent to consider + * @param distance the distance to the agent + */ + virtual void filterAgent(const BaseAgent *agent, float distance); + + /*! + * @brief filters an obstacle and determines if it needs to be in the near set + * + * @param obstacle the obstacle to consider + * @param distance the distance to the obstacle + */ + virtual void filterObstacle(const Obstacle *, float distance); + + /*! + * @brief gets the start point for the query + * + * @returns the query point for this filter + */ + virtual Vector2 getQueryPoint(){ return _pos;}; + + /*! + * @brief updates the max agent query range if conditions inside the filter are met + * typically, we don't shrink the query range until the result set is full + * + * @returns The Max query range. Typically this is the initial range unless some + * special conditions are met + */ + virtual float getMaxAgentRange(); + + /*! + * @brief updates the max query obstacle range if conditions inside the filter are met + * typically, we don't shrink the query range until the result set is full + * + * @returns The Max query range. Typically this is the initial range unless some + * special conditions are met + */ + virtual float getMaxObstacleRange() { return _neighborDist * _neighborDist;}; + }; + } // namespace Agents +} // namespace Menge +#endif // __BASE_AGENT_H__ diff --git a/src/Menge/MengeCore/Agents/Elevations/Elevation.h b/src/Menge/MengeCore/Agents/Elevations/Elevation.h new file mode 100644 index 00000000..75a75b64 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/Elevation.h @@ -0,0 +1,162 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Elevation.h + * @brief The definition of the elevation element. This approximately allows + * for agents to be simulated on non-planer domains. + */ +#ifndef __ELEVATION_H__ +#define __ELEVATION_H__ + +#include "mengeCommon.h" +#include "Element.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class BaseAgent; + + /*! + * @brief Exception class for elevation computation. + */ + class MENGE_API ElevationException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + ElevationException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ElevationException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal elevation exception. + */ + class MENGE_API ElevationFatalException : public ElevationException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + ElevationFatalException() : MengeException(), ElevationException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ElevationFatalException( const std::string & s ): MengeException(s), ElevationException(), MengeFatalException() {} + }; + + + /*! + * @brief The base class for determining an agent's elevation. + * + * This is an abstract class, primarily defining the Elevation abstraction. + * Essentially, the Elevation object must be able to report elevation for + * an agent (or an arbitrary position) and the "gradient" at that point. + * + * The gradient is not *truly* the gradient. In fact, it is merely the + * projection of the elevation object's normal on the planning plane. So, + * if the elevation is parallel to the planning plane, the gradient would be + * the vector \<0, 0\>. If the elevation surface is perpendicular to the + * planning plane (a highly unlikely contingent) it would be the vector \ + * such that the magnitude of that vector is 1. + */ + class MENGE_API Elevation : public Element { + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~Elevation(){} + + public: + /*! + * @brief Reports the elevation of the simulation domain at the given point. + * + * The domain may have more than one valid elevation for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The elevation at the given point. + */ + virtual float getElevation( const Vector2 & point ) const = 0; + + /*! + * @brief Reports the elevation of the simulation domain for the given agent + * + * The domain may have more than one valid elevation for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param agent A pointer to the agent for which elevation should be reported. + * @returns The elevation (position on the y-axis) based on current agent state/position. + */ + virtual float getElevation( const BaseAgent * agent ) const = 0; + + /*! @brief Reports the gradient of the simulation domain at the given point. + * + * The domain may have more than one valid gradient for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The gradient at the given point. + */ + virtual Vector2 getGradient( const Vector2 & point ) const = 0; + + /*! + * @brief Reports the gradient of the simulation domain for the given agent + * + * The domain may have more than one valid gradient for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param agent A pointer to the agent for which gradient should be reported. + * @returns The gradient of the domain based on current agent state/position. + */ + virtual Vector2 getGradient( const BaseAgent * agent ) const = 0; + }; + + } // namespace Agents +} // + +#endif // __ELEVATION_H__ diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.cpp b/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.cpp new file mode 100644 index 00000000..9af1b2bf --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.cpp @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ElevationDatabase.h" +#include "Elevations/ElevationFlat.h" +#include "Elevations/ElevationNavMesh.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< Agents::ElevationFactory, Agents::Elevation >::getElementName() { return "elevation"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< Agents::ElevationFactory, Agents::Elevation >::addBuiltins() { + addFactory( new Agents::FlatElevationFactory() ); + addFactory( new Agents::NavMeshElevationFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.h b/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.h new file mode 100644 index 00000000..05aa012d --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationDatabase.h @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElevationDatabase.h + * @brief Central database for querying available elevation implementations. + * + * For elevations to be used in simulation, they must register + * themselves into the ElevationDatabase. This is done via the PluginEngine. + */ + +#ifndef __ELEVATION_DATABASE_H__ +#define __ELEVATION_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Elevations/ElevationFactory.h" +#include "Elevations/Elevation.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered elevation implementations. + */ + typedef ElementDB< ElevationFactory, Elevation > ElevationDB; + + } // namespace Agents + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< Agents::ElevationFactory, Agents::Elevation >::addBuiltins(); + template<> std::string ElementDB< Agents::ElevationFactory, Agents::Elevation >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS +} // namespace Menge + +#endif // __ELEVATION_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationFactory.h b/src/Menge/MengeCore/Agents/Elevations/ElevationFactory.h new file mode 100644 index 00000000..c8287684 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationFactory.h @@ -0,0 +1,62 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElevationFactory.h + * @brief The factory for parsing xml data and instantiating + * elevation implementations. + */ + +#ifndef __ELEVATION_FACTORY_H__ +#define __ELEVATION_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "Elevations/Elevation.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief A class for parsing the xml description of an action + * and instantiating particular instances. + */ + class MENGE_API ElevationFactory : public ElementFactory< Elevation > {}; + } // namespace Agents +} // namespace Menge +#endif // __ELEVATION_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.cpp b/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.cpp new file mode 100644 index 00000000..b26a7f14 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.cpp @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ElevationFlat.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of FlatElevation + //////////////////////////////////////////////////////////////////////////// + + float FlatElevation::getElevation( const Vector2 & point ) const { + return 0.f; + } + + //////////////////////////////////////////////////////////////////////////// + + float FlatElevation::getElevation( const BaseAgent * agent ) const { + return 0.f; + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 FlatElevation::getGradient( const Vector2 & point ) const { + return Vector2( 0.f, 0.f ); + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 FlatElevation::getGradient( const BaseAgent * agent ) const { + return Vector2( 0.f, 0.f ); + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.h b/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.h new file mode 100644 index 00000000..ccde5a7b --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationFlat.h @@ -0,0 +1,141 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElevationFlat.h + * @brief The definition of an elevation class for flat ground; + * elevation is always zero and gradient is always <0,0>. + */ + +#ifndef __ELEVATION_FLAT_H__ +#define __ELEVATION_FLAT_H__ + +// Menge Base +#include "mengeCommon.h" +#include "Elevations/Elevation.h" +#include "Elevations/ElevationFactory.h" + +namespace Menge { + + namespace Agents { + + /*! + * @brief Defintion of elevation class representing flat ground. + */ + class MENGE_API FlatElevation : public Elevation { + public: + /*! @brief Reports the elevation of the simulation domain at the given point. + * The domain may have more than one valid elevation for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The elevation at the given point. + */ + float getElevation( const Vector2 & point ) const; + + /*! + * @brief Reports the elevation of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which elevation should be reported. + * @returns The elevation (position on the y-axis) based on current agent state/position. + */ + float getElevation( const BaseAgent * agent ) const; + + /*! @brief Reports the gradient of the simulation domain at the given point. + * The domain may have more than one valid gradient for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The gradient at the given point. + */ + virtual Vector2 getGradient( const Vector2 & point ) const; + + /*! + * @brief Reports the gradient of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which gradient should be reported. + * @returns The gradient of the domain based on current agent state/position. + */ + Vector2 getGradient( const BaseAgent * agent ) const; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the FlatElevation. + */ + class MENGE_API FlatElevationFactory : public ElevationFactory { + public: + /*! + * @brief The name of the elevation. + * + * The elevation's name must be unique among all registered elevation components. + * Each elevation factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "flat"; } + + /*! + * @brief A description of the elevation. + * + * Each elevation factory must override this function. + * + * @returns A string containing the elevation description. + */ + virtual const char * description() const { + return "Provides the elevation data for a flat plane, located at zero elevation."; + }; + + protected: + /*! + * @brief Create an instance of this class's elevation implementation. + * + * All ElevationFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding elevation type. The various field values + * of the instance will be set in a subsequent call to ElevationFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Elevation class. + */ + Elevation * instance() const { return new FlatElevation(); } + }; + + } // namespace Agents +} // namespace Menge +#endif // __ELEVATION_FLAT_H__ diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.cpp b/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.cpp new file mode 100644 index 00000000..1a9b2d2e --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.cpp @@ -0,0 +1,149 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Elevations/ElevationNavMesh.h" +#include "Tasks/NavMeshLocalizerTask.h" +#include "BaseAgent.h" +#include "tinyxml.h" +#include "os.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////// + // Implementation of NavMeshElevation + //////////////////////////////////////////////////////////////// + + NavMeshElevation::NavMeshElevation(): Elevation(), _navMesh(0x0), _localizer(0x0) { + } + + //////////////////////////////////////////////////////////////// + + float NavMeshElevation::getElevation( const Vector2 & point ) const { + unsigned int nodeID = _localizer->getNode( point ); + if ( nodeID == NavMeshLocation::NO_NODE ) { + return 0.f; + } else { + return _navMesh->getElevation( nodeID, point ); + } + } + + //////////////////////////////////////////////////////////////// + + float NavMeshElevation::getElevation( const BaseAgent * agent ) const { + unsigned int nodeID = _localizer->getNode( agent ); + if ( nodeID == NavMeshLocation::NO_NODE ) { + return 0.f; + } else { + return _navMesh->getElevation( nodeID, agent->_pos ); + } + } + + //////////////////////////////////////////////////////////////// + + Vector2 NavMeshElevation::getGradient( const BaseAgent * agent ) const { + unsigned int nodeID = _localizer->getNode( agent ); + if ( nodeID == NavMeshLocation::NO_NODE ) { + return Vector2( 0.f, 0.f ); + } else { + return _navMesh->getGradient( nodeID, agent->_pos ); + } + } + + //////////////////////////////////////////////////////////////// + + Vector2 NavMeshElevation::getGradient( const Vector2 & point ) const { + unsigned int nodeID = _localizer->getNode( point ); + if ( nodeID == NavMeshLocation::NO_NODE ) { + return Vector2( 0.f, 0.f ); + } else { + return _navMesh->getGradient( nodeID, point ); + } + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * NavMeshElevation::getTask() { + return new BFSM::NavMeshLocalizerTask( _navMesh->getName(), false /*usePlanner*/ ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshVCFactory + ///////////////////////////////////////////////////////////////////// + + NavMeshElevationFactory::NavMeshElevationFactory() : ElevationFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool NavMeshElevationFactory::setFromXML( Elevation * e, TiXmlElement * node, const std::string & specFldr ) const { + NavMeshElevation * nme = dynamic_cast< NavMeshElevation * >( e ); + assert( nme != 0x0 && "Trying to set attributes of a navigation mesh elevation component on an incompatible object" ); + + if ( ! ElevationFactory::setFromXML( nme, node, specFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, specFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + NavMeshPtr nmPtr; + try { + nmPtr = loadNavMesh( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh referenced on line " << node->Row() << "."; + return false; + } + nme->setNavMesh( nmPtr ); + // nav mesh localizer + NavMeshLocalizerPtr nmlPtr; + try { + nmlPtr = loadNavMeshLocalizer( fName, true ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh localizer required by the elevation on line " << node->Row() << "."; + return false; + } + nme->setNavMeshLocalizer( nmlPtr ); + + return true; + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.h b/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.h new file mode 100644 index 00000000..586da291 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Elevations/ElevationNavMesh.h @@ -0,0 +1,226 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElevationNavMesh.h + * @brief Defines elevation based on a navigation mesh. If + * an agent (or a point) cannot be located on the mesh, its + * elevation is zero. + */ + + +#ifndef __ELEVATION_NAV_MESH_H__ +#define __ELEVATION_NAV_MESH_H__ + +// Resources +#include "NavMesh.h" +#include "NavMeshLocalizer.h" + +// Menge Base +#include "mengeCommon.h" +#include "Elevations/Elevation.h" +#include "Elevations/ElevationFactory.h" + +// STL +#include + +namespace Menge { + + // forward declaration + namespace BFSM { + class Task; + } + + namespace Agents { + + /*! + * @brief Elevation definition based on a navigation mesh. + */ + class MENGE_API NavMeshElevation : public Elevation { + public: + /*! + * @brief Constructor + * + */ + NavMeshElevation(); + + /*! @brief Reports the elevation of the simulation domain at the given point. + * The domain may have more than one valid elevation for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The elevation at the given point. + */ + virtual float getElevation( const Vector2 & point ) const; + + /*! + * @brief Reports the elevation of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which elevation should be reported. + * @returns The elevation (position on the y-axis) based on current agent state/position. + */ + virtual float getElevation( const BaseAgent * agent ) const; + + /*! @brief Reports the gradient of the simulation domain at the given point. + * The domain may have more than one valid gradient for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The gradient at the given point. + */ + virtual Vector2 getGradient( const Vector2 & point ) const; + + /*! + * @brief Reports the gradient of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which gradient should be reported. + * @returns The gradient of the domain based on current agent state/position. + */ + virtual Vector2 getGradient( const BaseAgent * agent ) const; + + /*! + * @brief Sets the navigation mesh pointer. + * + * @param nm The managed pointer to the navigation mesh. + */ + void setNavMesh( const NavMeshPtr & nm ) { _navMesh = nm; } + + /*! + * @brief Sets the navigation mesh localizer pointer. + * + * @param nml The managed pointer to the navigation mesh localizer. + */ + void setNavMeshLocalizer( const NavMeshLocalizerPtr & nml ) { _localizer = nml; } + + /*! + * @brief Returns a pointer to the nav mesh localizer task. + * + * @returns A pointer to the nav mesh localizer task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual BFSM::Task * getTask(); + + protected: + /*! + * @brief The navigation mesh used to query elevation and gradient + */ + NavMeshPtr _navMesh; + + /*! + * @brief The localizer for identifying where the agents are in the + * navigation mesh. + */ + NavMeshLocalizerPtr _localizer; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the NavMeshElevation. + */ + class MENGE_API NavMeshElevationFactory : public ElevationFactory { + public: + /*! + * @brief Constructor. + */ + NavMeshElevationFactory(); + + /*! + * @brief The name of the elevation. + * + * The elevation's name must be unique among all registered elevation components. + * Each elevation factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "nav_mesh"; } + + /*! + * @brief A description of the elevation. + * + * Each elevation factory must override this function. + * + * @returns A string containing the elevation description. + */ + virtual const char * description() const { + return "Provides elevation based on location on a navigation mesh."; + }; + + protected: + /*! + * @brief Create an instance of this class's elevation implementation. + * + * All ElevationFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding elevation type. The various field values + * of the instance will be set in a subsequent call to ElevationFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Elevation class. + */ + Elevation * instance() const { return new NavMeshElevation(); } + + /*! + * @brief Given a pointer to an Elevation instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Elevation's type. + * (i.e. ElevationFactory::thisFactory has already been called and returned true.) + * If sub-classes of ElevationFactory introduce *new* Elevation parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param e A pointer to the elevation whose attributes are to be set. + * @param node The XML node containing the elevation attributes. + * @param specFldr The path to the specification file. If the Elevation references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Elevation * e, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; + } // namespace Agents +} // namespace Menge +#endif // __ELEVATION_NAV_MESH_H__ + diff --git a/src/Menge/MengeCore/Agents/Events/AgentEventEffect.cpp b/src/Menge/MengeCore/Agents/Events/AgentEventEffect.cpp new file mode 100644 index 00000000..b9dbd013 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/AgentEventEffect.cpp @@ -0,0 +1,67 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentEventEffect.h" +#include "AgentEventTarget.h" +#include "BaseAgent.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of AgentEventEffect + ///////////////////////////////////////////////////////////////////// + + void AgentEventEffect::apply( EventTarget * target ) { + assert( dynamic_cast< AgentEventTarget * >( target ) != 0x0 && "Incompatible target type passed to an AgentEventEffect instance" ); + // static cast assumes that the previous assertion is valid + AgentEventTarget * tgt = static_cast< AgentEventTarget * >( target ); + // iterate through the target set, manipulating + std::vector< Agents::BaseAgent * >::iterator itr = tgt->begin(); + std::vector< Agents::BaseAgent * >::iterator end = tgt->end(); + for ( ; itr != end; ++itr ) { + agentEffect( *itr ); + } + } + + ///////////////////////////////////////////////////////////////////// + + bool AgentEventEffect::isCompatible( EventTarget * target ) { + return dynamic_cast< AgentEventTarget * >( target ) != 0x0; + } + +} \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/AgentEventEffect.h b/src/Menge/MengeCore/Agents/Events/AgentEventEffect.h new file mode 100644 index 00000000..7b548143 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/AgentEventEffect.h @@ -0,0 +1,104 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentEventEffect.h + * @brief The definition of the agent event effect -- defines the agent-base + * effect. + */ + +#ifndef __AGENT_EVENT_EFFECT_H__ +#define __AGENT_EVENT_EFFECT_H__ + +#include "EventEffect.h" +#include "EventEffectFactory.h" + + +namespace Menge { + // forward declaration + class AgentEventTarget; + + namespace Agents { + class BaseAgent; + } + + /*! + * @brief The event effect class that operates on sets of agents. + */ + class MENGE_API AgentEventEffect : public EventEffect { + public: + + /*! + * @brief Reports if the given target is compatible with this effect. + * + * Each effect can only work on certain types of targets. This function + * reports if the given target works with this effect. + * + * @param target The target instance to test. + * @returns True if the target is a valid argument to EventEffect::apply, + * false, otherwise. + */ + virtual bool isCompatible( EventTarget * target ); + + /*! + * @brief Applies the effect to the simulation target. + * + * Not all targets work with all effects. The target passed here + * must have previously passed the EventEffect::isCompatible test to + * work. + * + * @param target The target to apply the event to. + */ + virtual void apply( EventTarget * target ); + + protected: + + /*! + * @brief The actual work of the effect. + * + * Sub-classes should implement this. It is the action to be taken for each + * agent. + * + * @param agent The agent to operate on. + */ + virtual void agentEffect( Agents::BaseAgent * agent ) = 0; + }; + +} // namespace Menge + +#endif // __AGENT_EVENT_EFFECT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/AgentEventTarget.h b/src/Menge/MengeCore/Agents/Events/AgentEventTarget.h new file mode 100644 index 00000000..acdc88de --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/AgentEventTarget.h @@ -0,0 +1,88 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentEventTarget.h + * @brief The definition of the event target for agents. + */ + +#ifndef __AGENT_EVENT_TARGET_H__ +#define __AGENT_EVENT_TARGET_H__ + +#include "Events/EventTarget.h" +#include "Events/EventTargetFactory.h" +#include + +namespace Menge { + /*! + * @brief The base class for all event targets which target agents. + * + * Event targets are fundamentally defined by what the target of the + * effect is. Each event target specifies a single kind of target. + * This event target produces a set of one or more agents to effect. + */ + class MENGE_API AgentEventTarget : public EventTarget { + public: + + /*! + * @brief Returns an iterator to the beginning of the target's elements. + */ + std::vector< Agents::BaseAgent * >::iterator begin() { return _elements.begin(); } + + /*! + * @brief Returns an iterator to the end of the target's elements. + */ + std::vector< Agents::BaseAgent * >::iterator end() { return _elements.end(); } + + protected: + /*! + * @brief The agents targeted by the event effect. + */ + std::vector< Agents::BaseAgent * > _elements; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the AgentEventTarget. + */ + class MENGE_API AgentEventTargetFactory : public EventTargetFactory { + }; + +} // namespace Menge +#endif // __AGENT_EVENT_TARGET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/AgentPropertyEffect.h b/src/Menge/MengeCore/Agents/Events/AgentPropertyEffect.h new file mode 100644 index 00000000..8c7861a3 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/AgentPropertyEffect.h @@ -0,0 +1,295 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AgentPropertyEffect.h + * @brief The definition of an event effect that modifies agent + * properties. + */ + +#ifndef __AGENT_PROPERT_EFFECT_H__ +#define __AGENT_PROPERT_EFFECT_H__ + +#include "EventEffectFactory.h" +#include "AgentEventEffect.h" +#include "AgentPropertyManipulator.h" + +namespace Menge { + + // forward declaration + namespace Agents { + class BaseAgent; + } + + /*! + * @brief The base class event effect changes agent properties. + * + * This is an abstract class and must be sub-classed. To create different + * types of event effects, simply specialize this templated class with + * a different type of AgentPropertyManipulator. + */ + template + class MENGE_API AgentPropertyEffect : public AgentEventEffect { + public: + /*! + * @brief Constructor + */ + AgentPropertyEffect(): AgentEventEffect(), _manip() {} + + /*! + * @brief Returns a pointer to the manipulator. + */ + Manipulator * getManipulator() { return &_manip; } + + protected: + + /*! + * @brief The actual work of the effect. + * + * Sub-classes should implement this. It is the action to be taken for each + * agent. + * + * @param agent The agent to operate on. + */ + virtual void agentEffect( Agents::BaseAgent * agent ) { _manip.manipulate( agent ); } + + /*! + * @brief The manipulator responsible for changing agent properties. + */ + Manipulator _manip; + }; + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for agent property event effects. + */ + template < class Manipulator > + class MENGE_API AgentPropertyEffectFactory : public EventEffectFactory { + public: + /*! + * @brief Constructor. + */ + AgentPropertyEffectFactory() : EventEffectFactory() { + _propertyID = _attrSet.addStringAttribute( "property", true /*required*/ ); + _generatorID = _attrSet.addFloatDistAttribute( "", true /*required*/, 0.f, 1.f ); + } + + protected: + /*! + * @brief Given a pointer to an AgentPropertyEffect instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this AgentPropertyEffect's type. + * (i.e. EventEffectFactory::thisFactory has already been called and returned true.) + * If sub-classes of EventEffectFactory introduce *new* EventEffect parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param effect A pointer to the effect whose attributes are to be set. + * @param node The XML node containing the event effect attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( EventEffect * effect, TiXmlElement * node, const std::string & behaveFldr ) const { + AgentPropertyEffect< Manipulator > * aEffect = dynamic_cast< AgentPropertyEffect< Manipulator > * >( effect ); + assert( aEffect != 0x0 && "Trying to set agent event effect properties on an incompatible object" ); + + // This parses the target + if ( ! EventEffectFactory::setFromXML( aEffect, node, behaveFldr ) ) return false; + + // Configure manipulator + AgentPropertyManipulator * manip = aEffect->getManipulator(); + + BFSM::PropertyOperand prop = parsePropertyName( _attrSet.getString( _propertyID ) ); + manip->setProperty( prop ); + if ( prop == BFSM::NO_PROPERTY ) { + logger << Logger::ERR_MSG << "The property event effect defined on line " << node->Row() << " specified an invalid value for the \"property\" attribute"; + return false; + } + manip->setGenerator( _attrSet.getFloatGenerator( _generatorID ) ); + + return true; + } + + /*! + * @brief The identifier for the "property" string attribute. + */ + size_t _propertyID; + + /*! + * @brief The identifier for the float distribution attribute. + */ + size_t _generatorID; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the SetPropertyEffect. + */ + class MENGE_API SetAgentPropertyEffectFactory : public AgentPropertyEffectFactory< SetPropertyManipulator > { + public: + + /*! + * @brief The name of the effect. + * + * The effect's name must be unique among all registered effect. + * Each effect factory must override this function. + * + * @returns A string containing the unique effect name. + */ + virtual const char * name() const { return "set_agent_property"; } + + /*! + * @brief A description of the effect. + * + * Each effect factory must override this function. + * + * @returns A string containing the effect description. + */ + virtual const char * description() const { + return "Causes the specified property to be *replaced* by the user-defined value"; + }; + + protected: + /*! + * @brief Create an instance of this class's effect. + * + * All EventEffectFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding event effect type. The various field values + * of the instance will be set in a subsequent call to EventEffectFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EventEffect class. + */ + EventEffect * instance() const { return new AgentPropertyEffect< SetPropertyManipulator >(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the OffsetPropertyEffect. + */ + class MENGE_API OffsetAgentPropertyEffectFactory : public AgentPropertyEffectFactory< OffsetPropertyManipulator > { + public: + + /*! + * @brief The name of the effect. + * + * The effect's name must be unique among all registered effect. + * Each effect factory must override this function. + * + * @returns A string containing the unique effect name. + */ + virtual const char * name() const { return "offset_agent_property"; } + + /*! + * @brief A description of the effect. + * + * Each effect factory must override this function. + * + * @returns A string containing the effect description. + */ + virtual const char * description() const { + return "Causes the specified property to be offset by the user-defined value"; + }; + + protected: + /*! + * @brief Create an instance of this class's effect. + * + * All EventEffectFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding event effect type. The various field values + * of the instance will be set in a subsequent call to EventEffectFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EventEffect class. + */ + EventEffect * instance() const { return new AgentPropertyEffect< OffsetPropertyManipulator >(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ScalePropertyEffect. + */ + class MENGE_API ScaleAgentPropertyEffectFactory : public AgentPropertyEffectFactory< ScalePropertyManipulator > { + public: + + /*! + * @brief The name of the effect. + * + * The effect's name must be unique among all registered effect. + * Each effect factory must override this function. + * + * @returns A string containing the unique effect name. + */ + virtual const char * name() const { return "scale_agent_property"; } + + /*! + * @brief A description of the effect. + * + * Each effect factory must override this function. + * + * @returns A string containing the effect description. + */ + virtual const char * description() const { + return "Causes the specified property to be scaled by the user-defined value"; + }; + + protected: + /*! + * @brief Create an instance of this class's effect. + * + * All EventEffectFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding event effect type. The various field values + * of the instance will be set in a subsequent call to EventEffectFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EventEffect class. + */ + EventEffect * instance() const { return new AgentPropertyEffect< ScalePropertyManipulator >(); } + }; + +} // namespace Menge + +#endif // __AGENT_PROPERT_EFFECT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/Event.cpp b/src/Menge/MengeCore/Agents/Events/Event.cpp new file mode 100644 index 00000000..7e077757 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/Event.cpp @@ -0,0 +1,193 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Event.h" +#include "EventTrigger.h" +#include "EventResponse.h" +#include "Logger.h" +#include "EventException.h" +#include "EventSystem.h" +#include "EventTriggerDB.h" +#include "Core.h" +#include "tinyxml.h" +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Event + ///////////////////////////////////////////////////////////////////// + + Event::Event( const std::string & name ): _name(name), _trigger(0x0), _responses() { + } + + ///////////////////////////////////////////////////////////////////// + + Event::~Event() { + if ( _trigger) _trigger->destroy(); + for ( size_t i = 0; i < _responses.size(); ++i ) { + delete _responses[i]; + } + } + + ///////////////////////////////////////////////////////////////////// + + void Event::finalize() { + Logger::LogType logType = EventSystem::CONSERVATIVE_SETUP ? Logger::ERR_MSG : Logger::WARN_MSG; + bool error = false; + if ( _trigger ) { + try { + _trigger->finalize(); + } catch ( EventException & e ) { + _trigger->destroy(); + _trigger = 0x0; + logger << logType << "Event " << _name << " had problems finalizing its target: " << e._msg << "\n"; + error = true; + } + } else { + logger << logType << "Event " << _name << " is missing a trigger.\n"; + error = true; + } + + if ( _responses.size() > 0 ) { + std::vector< EventResponse * >::iterator itr = _responses.begin(); + while( itr != _responses.end() ) { + try { + (*itr)->finalize(); + ++itr; + } catch ( EventException & e ) { + delete *itr; + itr = _responses.erase( itr ); + logger << logType << "Event " << _name << " had problems finalizing a response: " << e._msg << "\n"; + error = true; + } + } + } else { + logger << logType << "Event " << _name << " has no responses defined."; + error = true; + } + + if ( error ) { + std::stringstream ss; + ss << "Finalization errors in event " << _name << "."; + if ( EventSystem::CONSERVATIVE_SETUP ) { + throw EventFatalException( ss.str() ); + } else { + if ( _trigger == 0x0 || _responses.size() == 0x0 ) { + throw EventException( ss.str() ); + } + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void Event::evaluate() { + assert( _responses.size() > 0 && "Evaluating an event with no responses!" ); + assert( _trigger != 0x0 && "Trying to evaluate an event with no trigger" ); + if ( _trigger->conditionMet() ) { + _trigger->fired(); + for ( size_t i = 0; i < _responses.size(); ++i ) { + _responses[i]->apply(); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + Event * parseEvent( TiXmlElement * node, const std::string & specFldr ) { + // extract name + const char * cName = node->Attribute( "name" ); + Event * evt = 0x0; + if ( cName != 0x0 ) { + std::string name( cName ); + evt = new Event( name ); + } else { + logger << Logger::ERR_MSG << "Event defined on line " << node->Row() << " is missing the \"name\" attribute."; + return 0x0; + } + + TiXmlElement* child; + for ( child = node->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == "Trigger" ) { + // parse the trigger + evt->_trigger = EventTriggerDB::getInstance( child, specFldr ); + if ( evt->_trigger == 0x0 ) { + delete evt; + return 0x0; + } + } else if ( child->ValueStr() == "Response" ) { + const char * eStr = child->Attribute( "effect" ); + if ( eStr == 0x0 ) { + logger << Logger::ERR_MSG << "Event response on line " << child->Row() << " requires an \"effect\" attribute."; + delete evt; + return 0x0; + } + const char * tStr = child->Attribute( "target" ); + if ( tStr == 0x0 ) { + logger << Logger::ERR_MSG << "Event response on line " << child->Row() << " requires an \"target\" attribute."; + delete evt; + return 0x0; + } + bool valid = true; + // test the names against the database + if ( EVENT_SYSTEM->_targets.find( tStr ) == EVENT_SYSTEM->_targets.end() ) { + logger << Logger::ERR_MSG << "An event has been assigned a target which doesn't exist in the system: " << tStr << "."; + valid = false; + } + if ( EVENT_SYSTEM->_effects.find( eStr ) == EVENT_SYSTEM->_effects.end() ) { + logger << Logger::ERR_MSG << "An event has been assigned an effect which doesn't exist in the system: " << eStr << "."; + valid = false; + } + if ( valid ) { + evt->_responses.push_back( new EventResponse( eStr, tStr ) ); + } else { + delete evt; + return 0x0; + } + } else { + logger << Logger::ERR_MSG << "Encountered unexpected child tag of Effects on line " << child->Row() << ": " << child->ValueStr() << "."; + delete evt; + return 0x0; + } + } + return evt; + } + +} \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/Event.h b/src/Menge/MengeCore/Agents/Events/Event.h new file mode 100644 index 00000000..c5ef8c4f --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/Event.h @@ -0,0 +1,135 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Event.h + * @brief The definition of the Menge Event. + */ + +#ifndef __EVENT_H__ +#define __EVENT_H__ + +#include +#include + +// forward declaration +class TiXmlElement; + +namespace Menge { + // forward declaration + class EventTrigger; + class EventResponse; + class Event; + class EventSystem; + + /////////////////////////////////////////////////////////////////////// + + /*! + * @brief Parses the xml specification of an event and returns a parsed + * event. + * + * The event instance will still need to be finalized. + * + * @param node The tiny xml node containing the event specification. + * @param specFldr The path to the specification file. All external + * resource references in the spec file are defined relative + * to this folder. + * @returns A new instance of an Event. Null if there is a parsing error. + * The caller assumes responsibility to delete the instance. + */ + Event * parseEvent( TiXmlElement * node, const std::string & specFldr ); + + /////////////////////////////////////////////////////////////////////// + + /*! + * @brief The definition of a Menge event. + * + * An event is defined by two components: a trigger, and a list of event *responses*. + * The trigger defines the circumstances which cause the event to "fire". + * The event can have multiple respones registered. When the event fires, + * each event response is triggered to modify the simulation. + */ + class Event { + public: + /*! + * @brief Constructor. + * + * @param name The name of the event. + */ + Event( const std::string & name ); + + /*! + * @brief Destructor. + */ + ~Event(); + + /*! + * @brief Allows the event to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventFatalException if the event system has conservative + * configuration and there is a problem in the event specification. + */ + void finalize(); + + /*! + * @brief Evaluates the event (and triggers handlers as necessary). + */ + void evaluate(); + + friend Event * parseEvent( TiXmlElement * node, const std::string & specFldr ); + friend class EventSystem; + protected: + /*! + * @brief The name of the event. + */ + std::string _name; + + /*! + * @brief The trigger for the event. + */ + EventTrigger * _trigger; + + /*! + * @brief The effects registered to this event. + */ + std::vector< EventResponse * > _responses; + }; +} // namespace Menge + +#endif // __EVENT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventEffect.h b/src/Menge/MengeCore/Agents/Events/EventEffect.h new file mode 100644 index 00000000..9bf11334 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventEffect.h @@ -0,0 +1,109 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventEffect.h + * @brief The definition of the event effect -- defines the response + * to a triggered response. + */ + +#ifndef __EVENT_EFFECT_H__ +#define __EVENT_EFFECT_H__ + +#include "CoreConfig.h" +#include "Element.h" + +namespace Menge { + // forward declaration + class EventTarget; + class EventEffectFactory; + + /*! + * @brief The definition of a response to an event. + * + * Event effects determine how the simulation changes due to a triggered + * event. The EventEffect is responsible for changing the simulation of the + * event target (and optionally caching the original state). Essentially, + * the event effect is the operator, and the corresponding EventTarget is + * the operand. + */ + class MENGE_API EventEffect : public Element { + public: + /*! + * @brief Constructor. + */ + EventEffect(): Element() {} + + /*! + * @brief Reports if the given target is compatible with this effect. + * + * Each effect can only work on certain types of targets. This function + * reports if the given target works with this effect. + * + * @param target The target instance to test. + * @returns True if the target is a valid argument to EventEffect::apply, + * false, otherwise. + */ + virtual bool isCompatible( EventTarget * target ) = 0; + + /*! + * @brief Applies the effect to the simulation target. + * + * Not all targets work with all effects. The target passed here + * must have previously passed the EventEffect::isCompatible test to + * work. + * + * @param target The target to apply the event to. + */ + virtual void apply( EventTarget * target ) = 0; + + /*! + * @brief Allows the event effect to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventException if there is a problem finalizing. + */ + virtual void finalize() {} + + friend class EventEffectFactory; + + }; + +} // namespace Menge + +#endif // __EVENT_EFFECT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventEffectDB.cpp b/src/Menge/MengeCore/Agents/Events/EventEffectDB.cpp new file mode 100644 index 00000000..db446a31 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventEffectDB.cpp @@ -0,0 +1,67 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventEffectDB.h" +#include "AgentPropertyEffect.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< EventEffectFactory, EventEffect >::getElementName() { return "event effect"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< EventEffectFactory, EventEffect >::addBuiltins() { + addFactory( new SetAgentPropertyEffectFactory() ); + addFactory( new OffsetAgentPropertyEffectFactory() ); + addFactory( new ScaleAgentPropertyEffectFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventEffectDB.h b/src/Menge/MengeCore/Agents/Events/EventEffectDB.h new file mode 100644 index 00000000..401cbaf7 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventEffectDB.h @@ -0,0 +1,68 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventEffectDB.h + * @brief Central database for querying available event effect implementations. + * + * For event effects to be used in simulation, they must register + * themselves into the EventEffectDB. This is done via the PluginEngine. + */ + +#ifndef __EVENT_EFFECT_DATABASE_H__ +#define __EVENT_EFFECT_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Events/EventEffectFactory.h" +#include "Events/EventEffect.h" + +namespace Menge { + /*! + * @brief The database of registered event effects implementations. + */ + typedef ElementDB< EventEffectFactory, EventEffect > EventEffectDB; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< EventEffectFactory, EventEffect >::addBuiltins(); + template<> std::string ElementDB< EventEffectFactory, EventEffect >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS +} // namespace Menge + +#endif // __EVENT_EFFECT_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/Events/EventEffectFactory.h b/src/Menge/MengeCore/Agents/Events/EventEffectFactory.h new file mode 100644 index 00000000..08c2acb7 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventEffectFactory.h @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventEffectFactory.h + * @brief The definition of the basic event effect factory. + */ + +#ifndef __EVENT_EFFECT_FACTORY_H__ +#define __EVENT_EFFECT_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "Events/EventEffect.h" + +namespace Menge { + + /*! + * @brief The base class for generating event effects. + */ + class MENGE_API EventEffectFactory : public ElementFactory< EventEffect > { + }; + +} // namespace Menge +#endif // __EVENT_EFFECT_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventException.h b/src/Menge/MengeCore/Agents/Events/EventException.h new file mode 100644 index 00000000..a67c041f --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventException.h @@ -0,0 +1,89 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventException.h + * @brief The definition of event-related exceptions. + */ + +#ifndef __EVENT_EXCEPTION_H__ +#define __EVENT_EXCEPTION_H__ + +#include "MengeException.h" +#include + +namespace Menge { + /*! + * @brief The base event exception. + */ + class MENGE_API EventException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + EventException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + EventException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal event exception. + */ + class MENGE_API EventFatalException : public EventException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + EventFatalException() : MengeException(), EventException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + EventFatalException( const std::string & s ):MengeException(s), EventException(), MengeFatalException() {} + }; + +} // namespace Menge + +#endif // __EVENT_EXCEPTION_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventResponse.cpp b/src/Menge/MengeCore/Agents/Events/EventResponse.cpp new file mode 100644 index 00000000..951c475e --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventResponse.cpp @@ -0,0 +1,97 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventResponse.h" +#include "EventEffect.h" +#include "EventTarget.h" +#include "Logger.h" +#include "EventException.h" +#include "EventSystem.h" +#include "Core.h" +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of EventResponse + ///////////////////////////////////////////////////////////////////// + + EventResponse::EventResponse() : _effectName(), _effect(0x0), _targetName(), _target(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + EventResponse::EventResponse( const std::string & effect, const std::string & target ) : _effectName(effect), _effect(0x0), _targetName(target), _target(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + void EventResponse::finalize() { + // Find the target and effect from the event system + HASH_MAP< std::string, EventEffect * >::iterator eItr = EVENT_SYSTEM->_effects.find( _effectName ); + // Only asserting this reasonable because I tested the names + // at parse time. + assert ( eItr != EVENT_SYSTEM->_effects.end() && "Missing effect at response finalization" ); + + HASH_MAP< std::string, EventTarget * >::iterator tItr = EVENT_SYSTEM->_targets.find( _targetName ); + assert ( tItr != EVENT_SYSTEM->_targets.end() && "Missing target at response finalization" ); + + _effect = eItr->second; + _target = tItr->second; + // confirm compatability + if ( ! _effect->isCompatible( _target ) ) { + std::stringstream ss; + ss << "The target " << _targetName << " is incompatible with the event effect " << _effectName << "."; + EventSystem::finalizeException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void EventResponse::apply() { + _target->update(); + _effect->apply( _target ); + + } + + ///////////////////////////////////////////////////////////////////// + + + +} //namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventResponse.h b/src/Menge/MengeCore/Agents/Events/EventResponse.h new file mode 100644 index 00000000..7e183f19 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventResponse.h @@ -0,0 +1,109 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventResponse.h + * @brief A response to an event trigger. + */ + +#ifndef __EVENT_RESPONSE_H__ +#define __EVENT_RESPONSE_H__ + +#include + +namespace Menge { + + // forward declarations + class EventEffect; + class EventTarget; + + /*! + * @brief A response to an event trigger. It combines an effect with + * a target. + */ + class EventResponse { + public: + /*! + * @brief Constructor. + */ + EventResponse(); + + /*! + * @brief Constructor. + * + * @param effect The name of the effect for this response. + * @param target The name of the target for this response. + */ + EventResponse( const std::string & effect, const std::string & target ); + + /*! + * @brief Finalizes the response. + */ + void finalize(); + + /*! + * @brief Applies the response to the simulation. + */ + void apply(); + + protected: + /*! + * @brief The name of the effect. + */ + std::string _effectName; + + /*! + * @brief The effect in this response. + */ + EventEffect * _effect; + + /*! + * @brief The name of the target. + */ + std::string _targetName; + + /*! + * @brief The target for this response. + */ + EventTarget * _target; + }; + +} // namespace Menge + +#endif // __EVENT_RESPONSE_H__ + diff --git a/src/Menge/MengeCore/Agents/Events/EventSystem.cpp b/src/Menge/MengeCore/Agents/Events/EventSystem.cpp new file mode 100644 index 00000000..855dc97f --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventSystem.cpp @@ -0,0 +1,219 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventSystem.h" +#include "Event.h" +#include "EventTargetDB.h" +#include "EventEffectDB.h" +#include "EventException.h" +#include + +namespace Menge { + ///////////////////////////////////////////////////////////////////// + // Implementation of EventSystem + ///////////////////////////////////////////////////////////////////// + + bool EventSystem::CONSERVATIVE_SETUP = true; + + ///////////////////////////////////////////////////////////////////// + + EventSystem::EventSystem(): _events() { + } + + ///////////////////////////////////////////////////////////////////// + + EventSystem::~EventSystem() { + for ( size_t i = 0; i < _events.size(); ++i ) { + delete _events[i]; + } + for ( HASH_MAP< std::string, EventTarget * >::iterator itr = _targets.begin(); + itr != _targets.end(); ++itr ) { + itr->second->destroy(); + } + for ( HASH_MAP< std::string, EventEffect * >::iterator itr = _effects.begin(); + itr != _effects.end(); ++itr ) { + itr->second->destroy(); + } + + } + + ///////////////////////////////////////////////////////////////////// + + void EventSystem::evaluateEvents() { + for ( size_t i = 0; i < _events.size(); ++i ) { + _events[i]->evaluate(); + } + } + + ///////////////////////////////////////////////////////////////////// + + void EventSystem::finalize() { + HASH_MAP< std::string, EventTarget * >::iterator tgtItr = _targets.begin(); + while ( tgtItr != _targets.end() ) { + try { + tgtItr->second->finalize(); + ++tgtItr; + } catch ( Menge::EventFatalException & ex ) { + logger << Logger::ERR_MSG << "Fatal exception finalizing event target: " << tgtItr->first << "\n" << ex._msg; + throw ex; + } catch ( Menge::EventException & ex ) { + logger << Logger::WARN_MSG << "Removing invalid event target " << tgtItr->first << "!\n" << ex._msg; + tgtItr = _targets.erase( tgtItr ); + } + } + + HASH_MAP< std::string, EventEffect * >::iterator effItr = _effects.begin(); + while ( effItr != _effects.end() ) { + try { + effItr->second->finalize(); + ++effItr; + } catch ( Menge::EventFatalException & ex ) { + logger << Logger::ERR_MSG << "Fatal exception finalizing event effect: " << effItr->first << "\n" << ex._msg; + throw ex; + } catch ( Menge::EventException & ex ) { + logger << Logger::WARN_MSG << "Removing invalid event effect " << effItr->first << "!\n" << ex._msg; + effItr = _effects.erase( effItr ); + } + } + + std::vector< Event * >::iterator itr = _events.begin(); + while ( itr != _events.end() ) { + try { + (*itr)->finalize(); + ++itr; + } catch ( Menge::EventFatalException & ex ) { + logger << Logger::ERR_MSG << "Fatal exception finalizing events\n" << ex._msg; + throw ex; + } catch ( Menge::EventException & ex ) { + logger << Logger::WARN_MSG << "Removing event " << (*itr)->_name << "!\n" << ex._msg; + itr = _events.erase( itr ); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void EventSystem::finalizeException( const std::string msg ) { + if ( CONSERVATIVE_SETUP ) { + logger << Logger::ERR_MSG << msg ; + throw EventFatalException( msg ); + } else { + logger << Logger::WARN_MSG << msg ; + throw EventException( msg ); + } + } + + ///////////////////////////////////////////////////////////////////// + + bool EventSystem::parseEvents( TiXmlElement * node, const std::string & behaveFldr ) { + // First test for "conservative" attribute + int i; + if ( node->Attribute("conservative", &i ) ) { + Menge::EventSystem::CONSERVATIVE_SETUP = i != 0; + } + const int TARGET_PASS = 0; + const int EFFECT_PASS = 1; + const int EVENT_PASS = 2; + + const char * tags[] = { "Target", "Effect", "Event" }; + for ( int pass = 0; pass < 3; ++pass ) { + std::string TAG( tags[ pass] ); + // then parse events + TiXmlElement* child; + for ( child = node->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == TAG ) { + if ( pass == TARGET_PASS ) { + const char * cStr = child->Attribute( "name" ); + if ( cStr == 0x0 ) { + logger << Logger::ERR_MSG << "Event target on line " << child->Row() << " requires a \"name\" attribute."; + return false; + } else { + std::string name( cStr ); + if ( _targets.find( name ) != _targets.end() ) { + logger << Logger::ERR_MSG << "Found multiple event targets with the same name: " << name << "."; + return false; + } + EventTarget * target = EventTargetDB::getInstance( child, behaveFldr ); + if ( target == 0x0 ) { + return false; + } + _targets[ name ] = target; + } + } else if ( pass == EFFECT_PASS ) { + const char * cStr = child->Attribute( "name" ); + if ( cStr == 0x0 ) { + logger << Logger::ERR_MSG << "Event effect on line " << child->Row() << " requires a \"name\" attribute."; + return false; + } else { + std::string name( cStr ); + if ( _effects.find( name ) != _effects.end() ) { + logger << Logger::ERR_MSG << "Found multiple event effects with the same name: " << name << "."; + return false; + } + EventEffect * effect = EventEffectDB::getInstance( child, behaveFldr ); + if ( effect == 0x0 ) { + return false; + } + _effects[ name ] = effect; + } + } else if ( pass == EVENT_PASS ) { + Event * evt = parseEvent( child, behaveFldr ); + if ( evt == 0x0 ) { + return false; + } + _events.push_back( evt ); + } else { + std::stringstream ss; + ss << "Found invalid child of EventSystem tag: " << child->ValueStr() << "."; + if ( CONSERVATIVE_SETUP ) { + logger << Logger::ERR_MSG << ss.str(); + throw EventFatalException( ss.str() ); + } else { + // only print the message on the first pass + if ( pass == 0 ) logger << Logger::WARN_MSG << ss.str(); + } + } + } + } + } + return true; + } + + + +} \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventSystem.h b/src/Menge/MengeCore/Agents/Events/EventSystem.h new file mode 100644 index 00000000..f5f104ed --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventSystem.h @@ -0,0 +1,153 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventSystem.h + * @brief The definition of the core event system. + */ + +#ifndef __EVENT_SYSTEM_H__ +#define __EVENT_SYSTEM_H__ + +#include +#include "mengeCommon.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + // forward declaration + + class Event; + class EventResponse; + class EventEffect; + class EventTarget; + Event * parseEvent( TiXmlElement * node, const std::string & specFldr ); + + /*! + * @brief The main event engine -- causes event triggers to be evaluated + * and effects to be applied. + */ + class EventSystem { + public: + /*! + * @brief Constructor. + */ + EventSystem(); + + /*! + * @brief Destructor + */ + ~EventSystem(); + + /*! + * @brief Adds an event to the system. + * + * The system becomes the owner of the event and will take responsibility + * for deleting it. + * + * @param evt The event to add to the system. + */ + void addEvent( Event * evt ) { _events.push_back( evt ); } + + /*! + * @brief Evaluates the registered events + */ + void evaluateEvents(); + + /*! + * @brief Finalize the event system. + */ + void finalize(); + + /*! + * @brief Parses events from an "Events" tag. + * + * @param node The node containing the event system description. + * @param behaveFldr The folder containing the behavior specification. + * all event paths are defined relative to this folder. + * @returns True if parsing was successful, false otherwise. + */ + bool parseEvents( TiXmlElement * node, const std::string & behaveFldr ); + + /*! + * @brief Causes an event exception to be thrown based on the + * the system's tolerance for event configuration errors. + * + * @param msg The event associated with the problem. + * @throws EventException if the system is *not* conservative; i.e., + * configuration errors will be noted, but simulation will + * continue. + * @throws EventFatalException if the system *is* conservative. + */ + static void finalizeException( const std::string msg ); + + /*! + * @brief Global variable to indicate how event configuration errors + * should be handled. + * + * If true, event configuration errors result in fatal exceptions, if false + * they are merely warnings. + */ + static bool CONSERVATIVE_SETUP; + + friend class Event; + friend class EventEffect; + friend class EventTarget; + friend class EventResponse; + friend Event * parseEvent( TiXmlElement * node, const std::string & specFldr ); + + protected: + /*! + * @brief The events to process. + */ + std::vector< Event * > _events; + + /*! + * @brief A mapping from target names to targets. + */ + HASH_MAP< std::string, EventTarget * > _targets; + + /*! + * @brief A mapping from effect names to effects. + */ + HASH_MAP< std::string, EventEffect * > _effects; + }; +} + +#endif // __EVENT_SYSTEM_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTarget.cpp b/src/Menge/MengeCore/Agents/Events/EventTarget.cpp new file mode 100644 index 00000000..b37df65b --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTarget.cpp @@ -0,0 +1,38 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + diff --git a/src/Menge/MengeCore/Agents/Events/EventTarget.h b/src/Menge/MengeCore/Agents/Events/EventTarget.h new file mode 100644 index 00000000..a6fe360b --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTarget.h @@ -0,0 +1,98 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTarget.h + * @brief The definition of the base event target class. Defines what + * an event effect operates on. + */ + +#ifndef __EVENT_TARGET_H__ +#define __EVENT_TARGET_H__ + +#include "CoreConfig.h" +#include "Element.h" +#include "Core.h" + + +namespace Menge { + // forward declaration + namespace Agents { + class BaseAgent; + } + + /*! + * @brief The base class for all event targets. + * + * An event target defines the operand of an event effect. + * i.e., if the event effect defines how things change, the target + * defines which elements undergo the effect. + */ + class MENGE_API EventTarget : public Element { + public: + /*! + * @brief Constructor. + */ + EventTarget() : Element(), _lastUpdate(-1.f) {} + + /*! + * @brief Allows the event target to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventException if there is a problem finalizing. + */ + virtual void finalize() {} + + /*! + * @brief Gives the target a chance to update its knowledge of the + * target entities. + * + * If a sub-class needs to do particular computation to evaluate the target, + * it should be implemented here. + */ + virtual void update() { _lastUpdate = SIM_TIME; } + + protected: + /*! + * @brief The global time that the target was last updated. + */ + float _lastUpdate; + }; + +} // namespace Menge +#endif // __EVENT_TARGET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTargetDB.cpp b/src/Menge/MengeCore/Agents/Events/EventTargetDB.cpp new file mode 100644 index 00000000..d762ecf4 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTargetDB.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventTargetDB.h" +#include "StateMemberTarget.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< EventTargetFactory, EventTarget >::getElementName() { return "event target"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< EventTargetFactory, EventTarget >::addBuiltins() { + addFactory( new NamedStateMemberTargetFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTargetDB.h b/src/Menge/MengeCore/Agents/Events/EventTargetDB.h new file mode 100644 index 00000000..ba1a476a --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTargetDB.h @@ -0,0 +1,69 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTargetDB.h + * @brief Central database for querying available event target implementations. + * + * For event targets to be used in simulation, they must register + * themselves into the EventTargetDB. This is done via the PluginEngine. + */ + +#ifndef __EVENT_TARGET_DATABASE_H__ +#define __EVENT_TARGET_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Events/EventTargetFactory.h" +#include "Events/EventTarget.h" + +namespace Menge { + /*! + * @brief The database of registered event targets implementations. + */ + typedef ElementDB< EventTargetFactory, EventTarget > EventTargetDB; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< EventTargetFactory, EventTarget >::addBuiltins(); + template<> std::string ElementDB< EventTargetFactory, EventTarget >::getElementName(); + +#endif //DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __EVENT_TARGET_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/Events/EventTargetFactory.cpp b/src/Menge/MengeCore/Agents/Events/EventTargetFactory.cpp new file mode 100644 index 00000000..b37df65b --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTargetFactory.cpp @@ -0,0 +1,38 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + diff --git a/src/Menge/MengeCore/Agents/Events/EventTargetFactory.h b/src/Menge/MengeCore/Agents/Events/EventTargetFactory.h new file mode 100644 index 00000000..6bdd6d53 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTargetFactory.h @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTargetFactory.h + * @brief The definition of the basic event target factory. + */ + +#ifndef __EVENT_TARGET_FACTORY_H__ +#define __EVENT_TARGET_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "Events/EventTarget.h" + +namespace Menge { + + /*! + * @brief The base class for generating event targets. + */ + class MENGE_API EventTargetFactory : public ElementFactory< EventTarget > { + }; + +} // namespace Menge +#endif // __EVENT_TARGET_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTrigger.cpp b/src/Menge/MengeCore/Agents/Events/EventTrigger.cpp new file mode 100644 index 00000000..3c9bf632 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTrigger.cpp @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventTrigger.h" +#include "Core.h" + +namespace Menge { + ///////////////////////////////////////////////////////////////////// + // Implementation of EventTrigger + ///////////////////////////////////////////////////////////////////// + + bool EventTrigger::conditionMet() { + float elapsed = SIM_TIME - _lastFire; + if ( elapsed > _firePeriod ) { + return testCondition(); + } + return false; + } + + ///////////////////////////////////////////////////////////////////// + + void EventTrigger::fired() { + _lastFire = SIM_TIME; + } +} \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTrigger.h b/src/Menge/MengeCore/Agents/Events/EventTrigger.h new file mode 100644 index 00000000..141a8704 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTrigger.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTrigger.h + * @brief The definition of the basic event trigger mechanism. + */ + +#ifndef __EVENT_TRIGGER_H__ +#define __EVENT_TRIGGER_H__ + +#include "CoreConfig.h" +#include "Element.h" + +namespace Menge { + /*! + * @brief The base class for event triggers. + * + * An event trigger specifies the conditions under which an event is + * triggered (allowing registered event handlers to respond). + */ + class MENGE_API EventTrigger : public Element { + public: + /*! + * @brief Constructor. + */ + EventTrigger() : Element(), _firePeriod(0.f), _lastFire(-1e6) {} + + /*! + * @brief Allows the trigger to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventException if there is a problem finalizing. + */ + virtual void finalize() {} + + /*! + * @brief Evaluates the condition to see if it has been met. + * + * @returns True if the condition has been met, false otherwise. + */ + bool conditionMet(); + + /*! + * @brief Informs the trigger that the associated event effects + * have been applied (i.e. the event has been fired). + */ + void fired(); + + protected: + + /*! + * @brief Evaluates the condition to see if it has been met. + * + * This must be implemented by all sub-classes. + * + * @returns True if the condition has been met, false otherwise. + */ + virtual bool testCondition() = 0; + + /*! + * @brief The minimum time between two successive firings (in simulation seconds). + */ + float _firePeriod; + + /*! + * @brief The time of the last firing (global simulation time). + */ + float _lastFire; + }; + +} // namespace Menge +#endif // __EVENT_TRIGGER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTriggerDB.cpp b/src/Menge/MengeCore/Agents/Events/EventTriggerDB.cpp new file mode 100644 index 00000000..d9be52b2 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTriggerDB.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "EventTriggerDB.h" +#include "StateEvtTrigger.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< EventTriggerFactory, EventTrigger >::getElementName() { return "event trigger"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< EventTriggerFactory, EventTrigger >::addBuiltins() { + addFactory( new StatePopIncTriggerFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/EventTriggerDB.h b/src/Menge/MengeCore/Agents/Events/EventTriggerDB.h new file mode 100644 index 00000000..4c3c5a9f --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTriggerDB.h @@ -0,0 +1,69 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTriggerDB.h + * @brief Central database for querying available event trigger implementations. + * + * For event triggers to be used in simulation, they must register + * themselves into the EventTriggerDB. This is done via the PluginEngine. + */ + +#ifndef __EVENT_TRIGGER_DATABASE_H__ +#define __EVENT_TRIGGER_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Events/EventTriggerFactory.h" +#include "Events/EventTrigger.h" + +namespace Menge { + /*! + * @brief The database of registered event triggers implementations. + */ + typedef ElementDB< EventTriggerFactory, EventTrigger > EventTriggerDB; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< EventTriggerFactory, EventTrigger >::addBuiltins(); + template<> std::string ElementDB< EventTriggerFactory, EventTrigger >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __EVENT_TRIGGER_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/Events/EventTriggerFactory.h b/src/Menge/MengeCore/Agents/Events/EventTriggerFactory.h new file mode 100644 index 00000000..7857d56e --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/EventTriggerFactory.h @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file EventTriggerFactory.h + * @brief The definition of the basic event trigger factory. + */ + +#ifndef __EVENT_TRIGGER_FACTORY_H__ +#define __EVENT_TRIGGER_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "Events/EventTrigger.h" + +namespace Menge { + + /*! + * @brief The base class for generating event triggers. + */ + class MENGE_API EventTriggerFactory : public ElementFactory< EventTrigger > { + }; + +} // namespace Menge +#endif // __EVENT_TRIGGER_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.cpp b/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.cpp new file mode 100644 index 00000000..f2bb4c73 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.cpp @@ -0,0 +1,113 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateEvtTrigger.h" +#include "Core.h" +#include "FSM.h" +#include "State.h" +#include "EventSystem.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of StateEvtTrigger + ///////////////////////////////////////////////////////////////////// + + StateEvtTrigger::StateEvtTrigger() : EventTrigger(), _stateName(), _state(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + void StateEvtTrigger::finalize() { + _state = ACTIVE_FSM->getNode( _stateName ); + if ( _state == 0x0 ) { + std::stringstream ss; + ss << "Event trigger unable to to locate state " << _stateName << "."; + EventSystem::finalizeException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of StateEvtTriggerFactory + ///////////////////////////////////////////////////////////////////// + + StateEvtTriggerFactory::StateEvtTriggerFactory() : EventTriggerFactory() { + _stateID = _attrSet.addStringAttribute( "state", true, "" ); + } + + ///////////////////////////////////////////////////////////////////// + + bool StateEvtTriggerFactory::setFromXML( EventTrigger * trigger, TiXmlElement * node, const std::string & specFldr ) const { + StateEvtTrigger * sTrigger = dynamic_cast< StateEvtTrigger * >( trigger ); + assert( sTrigger != 0x0 && "Trying to set attributes of a state event trigger on an incompatible object" ); + + if ( ! EventTriggerFactory::setFromXML( sTrigger, node, specFldr ) ) return false; + + sTrigger->_stateName = _attrSet.getString( _stateID ); + + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of StatePopIncreaseTrigger + ///////////////////////////////////////////////////////////////////// + + // _lastPop is initialized to a ridiculously high number in order to keep + // the event from triggering upon initialization. The first call to + // testCondition will bring it back down. + StatePopIncreaseTrigger::StatePopIncreaseTrigger() : StateEvtTrigger(), _lastPop(100000000) { + } + + ///////////////////////////////////////////////////////////////////// + + void StatePopIncreaseTrigger::finalize() { + StateEvtTrigger::finalize(); + _lastPop = _state->getPopulation(); + } + + ///////////////////////////////////////////////////////////////////// + + bool StatePopIncreaseTrigger::testCondition() { + size_t currPop = _state->getPopulation(); + bool increased = currPop > _lastPop; + _lastPop = currPop; + return increased; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.h b/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.h new file mode 100644 index 00000000..7bec54fb --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/StateEvtTrigger.h @@ -0,0 +1,211 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateEvtTrigger.h + * @brief The definitin of event triggers which key on state properties. + */ + +#ifndef __STATE_EVT_TRIGGER_H__ +#define __STATE_EVT_TRIGGER_H__ + +#include "Events/EventTrigger.h" +#include "Events/EventTriggerFactory.h" + +namespace Menge { + + // forward declaration + class StateEvtTriggerFactory; + + namespace BFSM { + class State; + } + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The base class event triggers which depend on state properties. + */ + class MENGE_API StateEvtTrigger : public EventTrigger { + public: + /*! + * @brief Constructor. + */ + StateEvtTrigger(); + + /*! + * @brief Allows the trigger to finish initializing itself from its + * parsed state to its running state. + */ + virtual void finalize(); + + friend class StateEvtTriggerFactory; + + protected: + /*! + * @brief The name of the state. + */ + std::string _stateName; + + /*! + * @brief The state to operate on. + */ + BFSM::State * _state; + }; + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for state event triggers. + */ + class MENGE_API StateEvtTriggerFactory : public EventTriggerFactory { + public: + /*! + * @brief Constructor. + */ + StateEvtTriggerFactory(); + + protected: + /*! + * @brief Given a pointer to an EventTrigger instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this EventTrigger's type. + * (i.e. EventTrigger::thisFactory has already been called and returned true.) + * If sub-classes of EventTriggerFactory introduce *new* EventTrigger parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param trigger A pointer to the event trigger whose attributes are to be set. + * @param node The XML node containing the event trigger attributes. + * @param specFldr The path to the specification file. If the EventTrigger references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( EventTrigger * trigger, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "state" string attribute. + */ + size_t _stateID; + + }; + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A trigger that fires off when a state's population increases. + */ + class MENGE_API StatePopIncreaseTrigger : public StateEvtTrigger { + public: + /*! + * @brief Constructor. + */ + StatePopIncreaseTrigger(); + + /*! + * @brief Allows the trigger to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventException if there is a problem finalizing. + */ + virtual void finalize(); + + protected: + + /*! + * @brief Evaluates the condition to see if it has been met. + * + * This must be implemented by all sub-classes. + * + * @returns True if the condition has been met, false otherwise. + */ + virtual bool testCondition(); + + /*! + * @brief The population last time the state was examined. + */ + size_t _lastPop; + }; + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for StatePopIncreaseTrigger event triggers. + */ + class MENGE_API StatePopIncTriggerFactory : public StateEvtTriggerFactory { + public: + /*! + * @brief The name of the trigger type. + * + * The trigger's name must be unique among all registered triggers. + * Each trigger factory must override this function. + * + * @returns A string containing the unique trigger name. + */ + virtual const char * name() const { return "state_pop_increase"; } + + /*! + * @brief A description of the event trigger. + * + * Each trigger factory must override this function. + * + * @returns A string containing the trigger description. + */ + virtual const char * description() const { + return "Event trigger which fires when a state's population increases."; + }; + + protected: + /*! + * @brief Create an instance of this class's event trigger implementation. + * + * All EventTriggerFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding trigger type. The various field values + * of the instance will be set in a subsequent call to EventTriggerFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EventTrigger class. + */ + EventTrigger * instance() const { return new StatePopIncreaseTrigger(); } + }; + +} // namespace Menge +#endif // __STATE_EVT_TRIGGER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/StateMemberTarget.cpp b/src/Menge/MengeCore/Agents/Events/StateMemberTarget.cpp new file mode 100644 index 00000000..203497df --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/StateMemberTarget.cpp @@ -0,0 +1,102 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateMemberTarget.h" +#include "Core.h" +#include "FSM.h" +#include "State.h" +#include "EventSystem.h" +#include "SimulatorInterface.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NamedStateMemberTarget + ///////////////////////////////////////////////////////////////////// + + void NamedStateMemberTarget::finalize() { + _state = ACTIVE_FSM->getNode( _stateName ); + if ( _state == 0x0 ) { + std::stringstream ss; + ss << "Event target unable to to locate state " << _stateName << "."; + EventSystem::finalizeException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void NamedStateMemberTarget::update() { + if ( _lastUpdate != SIM_TIME ) { + _elements.clear(); + const size_t AGENT_COUNT = SIMULATOR->getNumAgents(); + for ( size_t i = 0; i < AGENT_COUNT; ++i ) { + Agents::BaseAgent * agent = SIMULATOR->getAgent( i ); + BFSM::State * state = ACTIVE_FSM->getCurrentState( agent ); + if ( ( state != _state ) ^ _inState ) { + _elements.push_back( agent ); + } + } + AgentEventTarget::update(); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NamedStateMemberTargetFactory + ///////////////////////////////////////////////////////////////////// + + NamedStateMemberTargetFactory::NamedStateMemberTargetFactory() : AgentEventTargetFactory() { + _stateID = _attrSet.addStringAttribute( "state", true, "" ); + _isMemberID = _attrSet.addBoolAttribute( "is_member", true, true ); + } + + ///////////////////////////////////////////////////////////////////// + + bool NamedStateMemberTargetFactory::setFromXML( EventTarget * target, TiXmlElement * node, const std::string & specFldr ) const { + NamedStateMemberTarget * sTarget = dynamic_cast< NamedStateMemberTarget * >( target ); + assert( sTarget != 0x0 && "Trying to set attributes of a state-membership event target on an incompatible object" ); + + if ( ! AgentEventTargetFactory::setFromXML( target, node, specFldr ) ) return false; + + sTarget->_stateName = _attrSet.getString( _stateID ); + sTarget->_inState = _attrSet.getBool( _isMemberID ); + + return true; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Events/StateMemberTarget.h b/src/Menge/MengeCore/Agents/Events/StateMemberTarget.h new file mode 100644 index 00000000..ee7ab19c --- /dev/null +++ b/src/Menge/MengeCore/Agents/Events/StateMemberTarget.h @@ -0,0 +1,193 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateMemberTarget.h + * @brief Defines an event effect target based on membership in state(s). + */ + +#ifndef __STATE_MEMBER_TARGET_H__ +#define __STATE_MEMBER_TARGET_H__ + +#include "AgentEventTarget.h" + +namespace Menge { + // forward declaration + class NamedStateMemberTargetFactory; + + namespace BFSM { + class State; + } + + + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Defines the target of an event effect based on membership + * relationship to a single *named* state. + */ + class MENGE_API NamedStateMemberTarget : public AgentEventTarget { + public: + /*! + * @brief Default constructor. + */ + NamedStateMemberTarget() : AgentEventTarget() {} + + /*! + * @brief Allows the event target to finish initializing itself from its + * parsed state to its running state. + * + * @throws EventException if there is a problem finalizing. + */ + virtual void finalize(); + + /*! + * @brief Gives the target a chance to update its knowledge of the + * target entities. + * + * If a sub-class needs to do particular computation to evaluate the target, + * it should be implemented here. + */ + virtual void update(); + + friend class NamedStateMemberTargetFactory; + + protected: + /*! + * @brief The name of the state to operate on. + */ + std::string _stateName; + + /*! + * @brief The state to operate on. + */ + BFSM::State * _state; + + /*! + * @brief Deterimines if membership in the specified state (true) + * or non-membership (false) makes an agent a target. + */ + bool _inState; + }; + + ///////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory to generate NamedStateMemberTarget instances. + */ + class MENGE_API NamedStateMemberTargetFactory : public AgentEventTargetFactory { + public: + /*! + * @brief Constructor. + */ + NamedStateMemberTargetFactory(); + + /*! + * @brief The name of the target. + * + * The target's name must be unique among all registered targets. + * Each target factory must override this function. + * + * @returns A string containing the unique target name. + */ + virtual const char * name() const { return "named_state_member"; } + + /*! + * @brief A description of the target. + * + * Each target factory must override this function. + * + * @returns A string containing the target description. + */ + virtual const char * description() const { + return "Defines an agent as a target based on its membership relationship to a single state."; + }; + + protected: + /*! + * @brief Create an instance of this class's target. + * + * All EventTargetFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding event target type. The various field values + * of the instance will be set in a subsequent call to EventTargetFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated EventTarget class. + */ + EventTarget * instance() const { return new NamedStateMemberTarget(); } + + /*! + * @brief Given a pointer to an EventTarget instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this EventTarget's type. + * (i.e. EventTargetFactory::thisFactory has already been called and returned true.) + * If sub-classes of EventTargetFactory introduce *new* EventTarget parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param target A pointer to the target whose attributes are to be set. + * @param node The XML node containing the target attributes. + * @param behaveFldr The path to the behavior file. If the target references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( EventTarget * target, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "state" string attribute. + */ + size_t _stateID; + + /*! + * @brief The identifier for the "is_member" bool attribute. + */ + size_t _isMemberID; + }; + + // TODO: Future state-based targets + // Set of named states + // membership based on state properties + // final/not final + // transitions to state X + // etc. + +} // namespace Menge +#endif // __STATE_MEMBER_TARGET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Obstacle.cpp b/src/Menge/MengeCore/Agents/Obstacle.cpp new file mode 100644 index 00000000..2bc6269c --- /dev/null +++ b/src/Menge/MengeCore/Agents/Obstacle.cpp @@ -0,0 +1,215 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + + +#include "Obstacle.h" +#include "Math/geomQuery.h" +#include "Math/consts.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of Obstacle + ///////////////////////////////////////////////////////////////////////////// + + Obstacle::Obstacle() : _doubleSided(false), _isConvex(false), _nextObstacle(0x0), _point(), _prevObstacle(0x0), _unitDir(), _id(0), _class(0x1) { + } + + ///////////////////////////////////////////////////////////////////////////// + + Obstacle::~Obstacle() { + } + + ///////////////////////////////////////////////////////////////////////////// + + Vector2 Obstacle::getP1() const { + if ( _nextObstacle != 0x0 ) { + return _nextObstacle->_point; + } else { + return _point + _unitDir * _length; + } + } + + ///////////////////////////////////////////////////////////////////////////// + + Obstacle::NearTypeEnum Obstacle::distanceSqToPoint( const Vector2 & pt, Vector2 & nearPt, float & distSq ) const { + Vector2 P1 = getP1(); + Vector2 ba( P1 - _point ); + Vector2 ca( pt - _point ); + float r = ( ca * ba ) / absSq( ba ); + + if (r < 0) { // point a is closest to c + nearPt.set( _point ); + distSq = absSq( ca ); + return FIRST; + } else if (r > 1) { // point b is closest to c + nearPt.set( P1 ); + distSq = absSq( nearPt - pt ); + return LAST; + } else { // some point in between a and b is closest to c + nearPt.set( _point + ba*r ); + distSq = absSq( nearPt - pt ); + return MIDDLE; + } + } + + ///////////////////////////////////////////////////////////////////////////// + + float Obstacle::circleIntersection( const Vector2 & dir, const Vector2 & start, float radius ) const { + const float radSqd = radius * radius; + const float SPEED = abs( dir ); + Vector2 forward( dir / SPEED ); + // Find the end points relative to the start position + Vector2 a = getP0() - start; + Vector2 b = getP1() - start; + + // rotate the segment so that the direction is aligned with the x-axis + // TODO: Where is this exploited??? + float x = a.x() * forward.x() + a.y() * forward.y(); + float y = a.y() * forward.x() - a.x() * forward.y(); + a.set( x, y ); + x = b.x() * forward.x() + b.y() * forward.y(); + y = b.y() * forward.x() - b.x() * forward.y(); + b.set( x, y ); + + // compute the implicit equation of the obstacle line + Vector2 disp = b - a; + float dist = abs( disp ); + Vector2 D = disp / dist; + Vector2 N( D.y(), -D.x() ); + float C = -( N * a ); // Ax + By + C = 0 --> implicit equation + // Test for collision + if ( C < 0.f ) { + // the agent lies on the "wrong" side of the obstacle and can't see it. + return INFTY; + } else if ( C < radius ) { // the circle overlaps the line on the visible side + float t = D * (-a); // projection of origin on the line + if ( t >= -radius && t <= dist + radius ) { + // The projection of the circle center lies within the projection of + // the minkowski sum on the line (i.e. extends past the points by + // a distance equal to the radius). + if ( ( t >=0 && t <= dist ) || + ( t < 0 && absSq( a ) < radSqd ) || + ( t > dist && absSq( b ) < radSqd ) ) { + return 0.f; + } + } + } + + // Not currently colliding -- now compute potential collision in the future + // M points to the side of the line on which the origin (aka agent) lies + // This creates the leading edge of the minkowski sum (defined by (a2, b2)). + Vector2 M( C < 0.f ? -N : N ); + Vector2 a2( a + M * radius ); + Vector2 b2( b + M * radius ); + // I use this to do quick and dirty floating-point SIGN tests + // This may not be particularly portable + union { + float f; + unsigned int u; + } w1, w2; + w1.f = a2.y(); + w2.f = b2.y(); + if ( ( w1.u ^ w2.u ) & 0x80000000 ) { + // signs of the y-values are different; the segment crosses the line + float t = -a2.y() / D.y(); + float x = a2.x() + D.x() * t; + if ( x > 0 ) { + // The time it takes to travel distance x + return x / SPEED; + } + } else { + // both end points are on the same side of the line + // Note: Both of these are possible if the obstacle is near parallel + // to the forward direction + float minT = INFTY; + float aDist2 = a.y() * a.y(); + if ( aDist2 < radSqd ) { + // collision with a + // dx < radius + float dx = sqrtf( radSqd - aDist2 ); + float x = a.x() - dx; // collision point candidate + // This is a bit tricky - I don't have to consider a.x() + dx + // 1) the direction is in the positive x-axis direction, so I know + // the earliest collision must have a lesser x-value. + // 2) It's POSSIBLE for x to have a negative value, but if that's + // true, then a.x() + dx must ALSO be negative, otherwise + // the point is inside the circle and it would be detected + // as a collision. So, it's enough to just test one value + if ( x > 0.f ) { + float t = x / ( dist * D.x() ); + if ( t < minT ) { + minT = t; + } + } + } + float bDist2 = b.y() * b.y(); + if ( bDist2 < radSqd ) { + // collision with a + // dx < radius + float dx = sqrtf( radSqd - bDist2 ); + float x = b.x() - dx; // collision point candidate + if ( x > 0.f ) { + float t = x / dir.x(); + if ( t < minT ) { + minT = t; + } + } + } + return minT; + } + return INFTY; + } + + ///////////////////////////////////////////////////////////////////////////// + + bool Obstacle::pointOnObstacle( const Vector2 &pt ) const { + Vector2 disp = pt - _point; + float t = disp * _unitDir; + // The point projects onto the line beyond the extents of the segment + if ( t > _length || t < 0.f ) return false; + float dispSq = absSq( disp ); + // the point doesn't lie on the line, because its displacement to the originating + // point is not the same as t^2. + if ( fabs( t * t - dispSq ) > 0.001f ) return false; + return true; + } + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/Obstacle.h b/src/Menge/MengeCore/Agents/Obstacle.h new file mode 100644 index 00000000..5433f935 --- /dev/null +++ b/src/Menge/MengeCore/Agents/Obstacle.h @@ -0,0 +1,271 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Obstacle.h + * @brief Contains the Obstacle class. + */ + +#ifndef OBSTACLE_H +#define OBSTACLE_H + +#include "mengeCommon.h" + +namespace Menge { + + namespace Agents { + + /*! + * @brief Defines static obstacles in the simulation. + */ + class MENGE_API Obstacle { + public: + /*! + * @brief An enumeration to define the type of nearest point - first, middle, last + */ + enum NearTypeEnum { + FIRST, + MIDDLE, + LAST + }; + + /*! + * @brief Constructs a static obstacle instance. + */ + Obstacle(); + + /*! + * @brief Destroys this static obstacle instance. + */ + ~Obstacle(); + + /*! + * @brief Retrieves the normal of the obstacle + * @returns The normal + */ + inline Vector2 normal() const { return Vector2( _unitDir.y(), -_unitDir.x() ); } + + /*! + * @brief Retrieve the first point on the obstacle. + */ + inline const Vector2 & getP0() const { return _point; } + + /*! + * @brief Retrieve the obstacle's mid-point. + */ + inline const Vector2 midPt() const { return _point + ( 0.5f * _length) * _unitDir; } + + /*! + * @brief Retrieve the second point on the obstacle. + */ + Vector2 getP1() const; + + /*! + * @brief Returns the next obstacle in sequence + */ + const Obstacle * next() const { return _nextObstacle; } + + /*! + * @brief Computes the squared distance from the obstacle to the given point. + * Also sets the value of the point in the provided Vector2 + * + * @param pt The point whose distance is to be evaluated + * @param nearPt The position on the obstacle which is nearest to the + * test point will be set here. + * @param distSq The squared distance to the line (i.e. ||pt - nearPt||^2) + * is placed inside this parameter. + * @returns The classificaiton of what the nearest point is - first, middle, or last + */ + NearTypeEnum distanceSqToPoint( const Vector2 & pt, Vector2 & nearPt, float & distSq ) const; + + /*! + * @brief Determines if a circle, moving along a ray, will intersect + * the obstacle. + * + * @param dir The direction of motion + * @param start The starting point of the circle + * @param radius The radius of the circle + * @returns The time to collision (a large value representing infinity + * if no collision is possible.) + */ + float circleIntersection( const Vector2 & dir, const Vector2 & start, float radius ) const; + + /*! + * @brief Returns the length of the obstacle + * + * @returns The length. + */ + inline float length() const { return _length; } + + /*! + * @brief Reports if the given point lies on the obstacle + * + * @param pt The point to test + * @returns True if pt is on the obstacle, false otherwise + */ + bool pointOnObstacle( const Vector2 & pt ) const; + + /*! + * @brief Reports if the given point is on the "outside" of + * the obstacle. This definition depends on whether the + * obstacle is double-sided or not. + * + * @param point The point to test. + * @returns A boolean reporting if the point lies on the outside of this + * obstacle (true) or not (false). + */ + // NOTE: This test is "safe" because if _doubleSided is true, the leftOf test doesn't + // get performed. If it is false, then _nextObstacle must point to a valid obstacle. + inline bool pointOutside( const Vector2 & point ) const { return _doubleSided || ( leftOf( _point, getP1(), point ) < 0.f ); } + + /*! + * @brief Reports if the obstacle is convext at _point. + * + * Takes into account the double-sidedness of the obstacle and the side + * of the obstacle the agent is on. + * + * @param agtOnRight Indicate if the agent is on the right side of + * the obstacle (true) or the left (false). + * @returns True if the obstacle is convex, false otherwise. + */ + inline bool p0Convex( bool agtOnRight) const { return agtOnRight ? _isConvex : _doubleSided && !_isConvex; } + + /*! + * @brief Reports if the obstacle is convext at _point + _length * _unitDir. + * + * Takes into account the double-sidedness of the obstacle and the side + * of the obstacle the agent is on. + * + * @param agtOnRight Indicate if the agent is on the right side of + * the obstacle (true) or the left (false). + * @returns True if the obstacle is convex, false otherwise. + */ + // NOTE: The only way for _nextObstacle to be NULL is for this to be double sided. + // And end points of double-sided obstacles are always convex. + inline bool p1Convex( bool agtOnRight) const { return _nextObstacle == 0x0 ? true : ( agtOnRight ? _nextObstacle->_isConvex : _doubleSided && _nextObstacle->_isConvex ); } + + /*! + * @brief Sets the obstacle's closed state. + * + * If closed, it is part of a sequence of obstacles that form a closed polygon. + * If open, it is part of a polyline. + * + * @param closed Defines the obstacle as part of a closed polygon (true), + * or a closed polygon (false). + */ + inline void setClosedState( bool closed ) { _doubleSided = !closed; } + + /*! + * @brief Reports if the obstacle is double sided. + * + * If double sided (true) then the obstacle should be included in the + * nearby obstacles, *regardless* of which side of the line the agent lies. + */ + bool _doubleSided; + + /*! + * @brief Reports if the obstacle is convex around the obstacle's + * point (_point). + */ + bool _isConvex; + + /*! + * @brief Pointer to the next obstacle in the greater obstacle structure. + * If the obstacle is open, it could be NULL. + */ + Obstacle* _nextObstacle; + + /*! + * @brief The point from which the obstacle is defined. + */ + Vector2 _point; + + /*! + * @brief Pointer to the previous obstacle in the greater obstacle structure. + * If the obstacle is open, it could be NULL. + */ + Obstacle* _prevObstacle; + + /*! + * @brief The direction the obstacle extends from the originating point. + */ + Vector2 _unitDir; + + /*! + * @brief The distance in the direction the obstacle extends. + */ + float _length; + + /*! + * @brief A unique identifier for this obstacle. + */ + size_t _id; + + /*! + * @brief The class of obstacle, used so agents can ignore/include obstacles + */ + size_t _class; + }; + + /*! + * @brief Computes the squared distance from a line segment with the + * specified endpoints to a specified point. + * + * @param a The first endpoint of the line segment. + * @param b The second endpoint of the line segment. + * @param c The point to which the squared distance is to + * be calculated. + * @returns The squared distance from the line segment to the point. + */ + inline MENGE_API float distSqPointLineSegment(const Vector2& a, const Vector2& b, + const Vector2& c) + { + const float r = ((c - a) * (b - a)) / absSq(b - a); + + if (r < 0.0f) { + return absSq(c - a); + } else if (r > 1.0f) { + return absSq(c - b); + } else { + return absSq(c - (a + r * (b - a))); + } + } + } // namespace Agents +} // namespace Menge +#endif + diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.cpp new file mode 100644 index 00000000..8dedaa23 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.cpp @@ -0,0 +1,140 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSets/ExplicitObstacleSet.h" +#include "tinyxml.h" +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ExplicitObstacleSet + //////////////////////////////////////////////////////////////////////////// + + ExplicitObstacleSet::ExplicitObstacleSet() : ListObstacleSet() { + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ExplicitObstacleSetFactory + //////////////////////////////////////////////////////////////////////////// + + bool ExplicitObstacleSetFactory::setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & specFldr ) const { + ExplicitObstacleSet * eSet = dynamic_cast< ExplicitObstacleSet * >( gen ); + assert( eSet != 0x0 && "Trying to set attributes of an explicit obstacle set on an incompatible object" ); + + if ( ! ObstacleSetFactory::setFromXML( eSet, node, specFldr ) ) return false; + + bool isClosed = false; + for( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "Obstacle" ) { + try { + ObstacleVertexList obs = parseObstacle( child); + eSet->addObstacle(obs); + } catch ( ObstacleSetException ) { + return false; + } + } else { + logger << Logger::WARN_MSG << "Found an unexpected child tag in an ObstacleSet on line " << node->Row() << ". Ignoring the tag: " << child->ValueStr() << "."; + } + } + + return true; + } + + ////////////////////////////////////////////////////////////////////////////// + + ObstacleVertexList ExplicitObstacleSetFactory::parseObstacle( TiXmlElement * node) const { + + int iVal; + // TODO: Simply eliminate the bounding box obstacle -- it is basically + // just ignored. + bool bb = false; + if ( node->Attribute( "boundingbox", &iVal ) ) { + // Skip bounding box obstacles, but treat it as normal + bb = (iVal != 0); + assert(!bb && "Bounding Boxes are depreciated!"); + } + ObstacleVertexList vList; + vList.closed = false; + if ( node->Attribute( "closed", &iVal ) ) { + vList.closed = (iVal != 0); + } + + double dVal; + bool valid = true; + + for ( TiXmlElement * vert = node->FirstChildElement(); vert; vert = vert->NextSiblingElement() ) { + if ( vert->ValueStr() == "Vertex") { + float p_x = 0; + float p_y = 0; + if ( vert->Attribute( "p_x", &dVal) ) { + p_x = (float)dVal; + } else { + valid = false; + } + if ( vert->Attribute( "p_y", &dVal) ) { + p_y = (float)dVal; + } else { + valid = false; + } + + if ( ! valid ) { + logger << Logger::ERR_MSG << "Obstacle vertex on line " << vert->Row() << " is missing the full x- and y-position specification."; + throw ObstacleSetFatalException("Obstacle vertex missing full specification"); + + } + vList.vertices.push_back( Vector2( p_x, p_y ) ); + } + else { + logger << Logger::WARN_MSG << "Encountered unexpected tag inside an obstacle definition on line " << vert->Row() << ": " << vert->ValueStr() << ". It will be ignored."; + } + + if ( ! valid ) { + logger << Logger::ERR_MSG << "Incomplete obstacle definition on line " << node->Row() << "."; + throw ObstacleSetFatalException("Incomplete obstacle definition"); + } + } + + return vList; + }; + } // namespace Agents +} // namespace Menge + + diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.h b/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.h new file mode 100644 index 00000000..02bc21ce --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ExplicitObstacleSet.h @@ -0,0 +1,144 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ExplicitObstacleSet.h + * @brief An obstacleset which creates obstacles based on explicit definitions in XML + */ + +#ifndef __EXPLICIT_OBSTACLE_SET_H__ +#define __EXPLICIT_OBSTACLE_SET_H__ + +#include "mengeCommon.h" +#include "ObstacleSets/ListObstacleSet.h" +#include "ObstacleSets/ObstacleSetFactory.h" +#include "Obstacle.h" +#include "ObstacleSets/ObstacleVertexList.h" +#include + +namespace Menge { + + namespace Agents { + + class ExplicitObstacleSetFactory; + /*! + * @brief Definition of obstacle set class which produces obstacles based on + * explicit definition in an XML file. + */ + class MENGE_API ExplicitObstacleSet : public ListObstacleSet { + public: + /*! + * @brief Constructor + */ + ExplicitObstacleSet(); + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for ExplicitGenerator + */ + class MENGE_API ExplicitObstacleSetFactory : public ObstacleSetFactory { + public: + /*! + * @brief The name of the obstacleset type. + * + * The set's name must be unique among all registered obstacleset components. + * Each obstacleset factory must override this function. + * + * @returns A string containing the unique obstacleset name. + */ + virtual const char * name() const { return "explicit"; } + + /*! + * @brief A description of the obstacle set + * + * Each obstacleset factory must override this function. + * + * @returns A string containing the obstacleset description. + */ + virtual const char * description() const { + return "Obstacle definitions given by explicit vertex lists in the XML specification."; + }; + + protected: + /*! + * @brief Create an instance of this class's obstacleset implementation. + * + * All ObstacleSetFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding ObstacleSet type. The various field values + * of the instance will be set in a subsequent call to ObstacleSetFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated ExplicitObstacleSet class. + */ + ObstacleSet * instance() const { return new ExplicitObstacleSet(); } + + /*! + * @brief Given a pointer to an ObstacleSet instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this ObstacleSet's type. + * (i.e. ObstacleSetFactory::thisFactory has already been called and returned true.) + * If sub-classes of ObstacleSetFactory introduce *new* ObstacleSet parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the ObstacleSet whose attributes are to be set. + * @param node The XML node containing the ObstacleSet attributes. + * @param specFldr The path to the specification file. If the ObstacleSet references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief Parses an obstacle position from an \ tag. + * + * @param node The XML node containing the agent definition. + * @returns Vector of Vector2s representing the obstacle parsed + * @throws ObstacleSetException if the Obstacle tag is mangled or incomplete + */ + ObstacleVertexList parseObstacle( TiXmlElement * node) const; + }; + } // namespace Agents +} // namespace Menge +#endif // __EXPLICIT_OBSTACLE_SET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.cpp new file mode 100644 index 00000000..2ed6e7bf --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.cpp @@ -0,0 +1,146 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSets/ListObstacleSet.h" +#include "tinyxml.h" +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ListObstacleSet + //////////////////////////////////////////////////////////////////////////// + + ListObstacleSet::ListObstacleSet() : ObstacleSet(), _obstacles() { + } + + //////////////////////////////////////////////////////////////////////////// + + ListObstacleSet::~ListObstacleSet() { + _obstacles.empty(); + } + + //////////////////////////////////////////////////////////////////////////// + + Obstacle * ListObstacleSet::getObstacle( size_t i ) { + if ( i >= _obstacles.size() ) { + throw ObstacleSetFatalException("Trying to access obstacle with invalid index value"); + } + return _obstacles[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////// + + bool ListObstacleSet::addObstacle(Obstacle *o) { + o->_class = _class; + o->_id = _obstacles.size(); + _obstacles.push_back(o); + return true; + }; + + ////////////////////////////////////////////////////////////////////////////// + + bool ListObstacleSet::addObstacle(ObstacleVertexList o){ + // TODO: confirm that class ID is truly a 2^k kind of value + // TODO: Do something with the open/close thing + if (o.vertices.size() < 2) { + throw ObstacleSetFatalException("Obstacle with too few vertices"); + } + + size_t firstId = _obstacles.size(); + size_t prevId = firstId-1; + const size_t VCOUNT = o.vertices.size(); + + for (size_t i = 0; i < VCOUNT - 1; ++i) { + Obstacle* obstacle = new Obstacle(); + obstacle->setClosedState( o.closed ); + + obstacle->_point = o.vertices[i]; + if (i > 0) { + obstacle->_prevObstacle = _obstacles[prevId]; + obstacle->_prevObstacle->_nextObstacle = obstacle; + } + + Vector2 dir = o.vertices[ i+1 ] - o.vertices[ i ]; + float length = abs( dir ); + obstacle->_length = length; + obstacle->_unitDir = dir / length; + // default case is that it is convex. + obstacle->_isConvex = true; + if ( i > 0 && VCOUNT > 2 ) { + obstacle->_isConvex = leftOf( o.vertices[ i-1 ], o.vertices[ i ], o.vertices[ i+1 ] ) >= 0; + } + + addObstacle(obstacle); + prevId = obstacle->_id; + } + + if ( o.closed ) { + // create an obstacle connecting the last vertex to the first vertex + Obstacle* obstacle = new Obstacle(); + obstacle->setClosedState( o.closed ); + obstacle->_point = o.vertices[ VCOUNT - 1 ]; + obstacle->_prevObstacle = _obstacles[prevId]; + obstacle->_prevObstacle->_nextObstacle = obstacle; + obstacle->_nextObstacle = _obstacles[ firstId ]; + obstacle->_nextObstacle->_prevObstacle = obstacle; + + Vector2 dir = o.vertices[ 0 ] - o.vertices[ VCOUNT - 1 ]; + float length = abs( dir ); + obstacle->_length = length; + obstacle->_unitDir = dir / length; + + // default case is that it is convex. + obstacle->_isConvex = true; + if ( VCOUNT > 2 ) { + obstacle->_isConvex = leftOf( o.vertices[ VCOUNT - 2 ], o.vertices[ VCOUNT - 1 ], o.vertices[ 0 ] ) >= 0; + Obstacle * obst = obstacle->_nextObstacle; + obst->_isConvex = leftOf( o.vertices[ VCOUNT - 1 ], o.vertices[ 0 ], o.vertices[ 1 ] ) >= 0; + } + + addObstacle(obstacle); + } + + return true; + + }; + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.h b/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.h new file mode 100644 index 00000000..532838b0 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ListObstacleSet.h @@ -0,0 +1,122 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ListObstacleSet.h + * @brief An abstract class for any obstacle set which will need an _obstacles list. Provides transformations from vertex vectors + */ + +#ifndef __LIST_OBSTACLE_SET_H__ +#define __LIST_OBSTACLE_SET_H__ + +#include "mengeCommon.h" +#include "ObstacleSets/ObstacleSet.h" +#include "ObstacleSets/ObstacleSetFactory.h" +#include "ObstacleSets/ObstacleVertexList.h" +#include "Obstacle.h" +#include + +namespace Menge { + + namespace Agents { + + /*! + * @brief Definition of obstacle set class which produces obstacles based on + * explicit definition in an XML file. + */ + class MENGE_API ListObstacleSet : public ObstacleSet { + public: + /*! + * @brief Constructor + */ + ListObstacleSet(); + + protected: + /*! + * @brief Destructor + */ + ~ListObstacleSet(); + + public: + /*! + * @brief Reports the number of obstacles in the set + * + * @returns The number of obstacles in this set + */ + virtual size_t obstacleCount() { return _obstacles.size(); } + + /*! + * @brief Get the ith obstacle. + * + * @param i The index of the requested obstacle. + * @returns The Obstacle object + * @throws ObstacleSetException if the index, i, is invalid. + */ + virtual Obstacle * getObstacle( size_t i ); + + /*! + * @brief Adds an obstacle to the generator + * + * @param o The Obstacle Object to be added + * @returns true if the obstacle was added successfully + * @throws ObstacleSetException if the obstacle is malformed + */ + bool addObstacle(Obstacle * o); + + /*! + * @brief Adds an obstacle to the generator from a list of vertices + * + * @param o ObstacleVertexList struct representing the incoming obstacle + * @returns true if the obstacle was added successfully + * @throws ObstacleSetException if the obstacle is malformed + */ + bool addObstacle(ObstacleVertexList o); + + friend class ExplicitObstacleSetFactory; + + protected: + /*! + * @brief The obstacles in an internal list + */ + std::vector< Obstacle *> _obstacles; + }; + + + } // namespace Agents +} // namespace Menge +#endif // __EXPLICIT_OBSTACLE_SET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.cpp new file mode 100644 index 00000000..15fd6890 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.cpp @@ -0,0 +1,101 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSets/NavMeshObstacleSet.h" +#include "tinyxml.h" +#include +#include "os.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of NavMeshObstacleSet + //////////////////////////////////////////////////////////////////////////// + + NavMeshObstacleSet::NavMeshObstacleSet() : ListObstacleSet() { + + } + + //////////////////////////////////////////////////////////////////////////// + + bool NavMeshObstacleSet::extractFromNavMesh(NavMeshPtr nm) { + std::vector obstacles = nm->getObstacles(); + std::vector::iterator vItr = obstacles.begin(); + for (;vItr != obstacles.end(); ++vItr){ + addObstacle(*vItr); + } + + return true; + }; + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ExplicitObstacleSetFactory + //////////////////////////////////////////////////////////////////////////// + + NavMeshObstacleSetFactory::NavMeshObstacleSetFactory() : ObstacleSetFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + //////////////////////////////////////////////////////////////////////////// + + bool NavMeshObstacleSetFactory::setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & specFldr ) const { + NavMeshObstacleSet * eSet = dynamic_cast< NavMeshObstacleSet * >( gen ); + assert( eSet != 0x0 && "Trying to set attributes of an explicit obstacle set on an incompatible object" ); + + if ( ! ObstacleSetFactory::setFromXML( eSet, node, specFldr ) ) return false; + + //get the absolute path for the file name + std::string fName; + std::string path = os::path::join( 2, specFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + NavMeshPtr nmPtr; + try { + nmPtr = loadNavMesh( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh referenced on line " << node->Row() << "."; + return false; + } + + return eSet->extractFromNavMesh(nmPtr); + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.h b/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.h new file mode 100644 index 00000000..e36b2708 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/NavMeshObstacleSet.h @@ -0,0 +1,157 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ExplicitObstacleSet.h + * @brief An obstacleset which creates obstacles based on explicit definitions in XML + */ + +#ifndef __NAVMESH_OBSTACLE_SET_H__ +#define __NAVMESH_OBSTACLE_SET_H__ + +#include "mengeCommon.h" +#include "ObstacleSets/ListObstacleSet.h" +#include "ObstacleSets/ObstacleSetFactory.h" +#include "Obstacle.h" +#include "NavMesh.h" +#include + +namespace Menge { + + namespace Agents { + + class NavMeshObstacleSetFactory; + /*! + * @brief Definition of obstacle set class which produces obstacles based on + * explicit definition in an XML file. + */ + class MENGE_API NavMeshObstacleSet : public ListObstacleSet { + public: + /*! + * @brief Constructor + */ + NavMeshObstacleSet(); + + /*! + * @brief Extract obstacles from a provided navigation_mesh + * + * @param nm The navigation mesh from which to extract obstacles + * @returns True if the obstacles were extracted successfully, false otherwise. + */ + bool extractFromNavMesh(NavMeshPtr nm); + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for NavMeshObstacleSet + */ + class MENGE_API NavMeshObstacleSetFactory : public ObstacleSetFactory { + public: + + /*! + * @brief constrcutor + */ + NavMeshObstacleSetFactory(); + + /*! + * @brief The name of the obstacleset type. + * + * The set's name must be unique among all registered obstacleset components. + * Each obstacleset factory must override this function. + * + * @returns A string containing the unique obstacleset name. + */ + virtual const char * name() const { return "nav_mesh"; } + + /*! + * @brief A description of the obstacle set + * + * Each obstacleset factory must override this function. + * + * @returns A string containing the obstacleset description. + */ + virtual const char * description() const { + return "Obstacle definitions extracted from a provided nav_mesh."; + }; + + protected: + /*! + * @brief Create an instance of this class's obstacleset implementation. + * + * All ObstacleSetFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding ObstacleSet type. The various field values + * of the instance will be set in a subsequent call to ObstacleSetFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated ExplicitObstacleSet class. + */ + ObstacleSet * instance() const { return new NavMeshObstacleSet(); } + + /*! + * @brief Given a pointer to an ObstacleSet instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this ObstacleSet's type. + * (i.e. ObstacleSetFactory::thisFactory has already been called and returned true.) + * If sub-classes of ObstacleSetFactory introduce *new* ObstacleSet parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the ObstacleSet whose attributes are to be set. + * @param node The XML node containing the ObstacleSet attributes. + * @param specFldr The path to the specification file. If the ObstacleSet references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & specFldr ) const; + + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + + }; + } // namespace Agents +} // namespace Menge + +#endif // __EXPLICIT_OBSTACLE_SET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.cpp new file mode 100644 index 00000000..4e9ecdd1 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.cpp @@ -0,0 +1,61 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSets/ObstacleSet.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ObstacleSet + ///////////////////////////////////////////////////////////////////// + + ObstacleSet::ObstacleSet(): Element(), _class(1) { + } + + ///////////////////////////////////////////////////////////////////// + + ObstacleSet::~ObstacleSet() { + + } + + ///////////////////////////////////////////////////////////////////// + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.h b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.h new file mode 100644 index 00000000..bc2b7e2e --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSet.h @@ -0,0 +1,162 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ObstacleSet.h + * @brief The definition of the ObstacleSet element + * Defines the numbers and positions of obstacles in a set + */ +#ifndef __OBSTACLE_SET_H__ +#define __OBSTACLE_SET_H__ + +#include "Element.h" +#include "MengeException.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class Obstacle; + class ObstacleSetFactory; + + /*! + * @brief Exception class for obstacle set instantiation + */ + class MENGE_API ObstacleSetException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + ObstacleSetException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ObstacleSetException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal obstacle set exception. + */ + class MENGE_API ObstacleSetFatalException : public ObstacleSetException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + ObstacleSetFatalException() : MengeException(), ObstacleSetException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ObstacleSetFatalException( const std::string & s ): MengeException(s), ObstacleSetException(), MengeFatalException() {} + }; + + + /*! + * @brief The base class for obstacle set definitions + * + * This is an abstract class defining the functions of an obstacle set in Menge + * Obstacle sets must be able to provide a count of Obstacles in their definition + * and pass those obstacles on to the SpatialQuery + */ + class MENGE_API ObstacleSet : public Element { + public: + /*! + * @brief Default constructor + */ + ObstacleSet(); + + friend class ObstacleSetFactory; + + protected: + /*! + * @brief Protected destructor. The destroy method should be used + * to delete an instance of an obstacle set. + */ + virtual ~ObstacleSet(); + + public: + + /*! + * @brief Reports the number of obstacles in the set. + * + * @returns The number of obstacles in this set. + */ + virtual size_t obstacleCount() = 0; + + /*! + * @brief Returns the ith obstacle. + * + * @param i The index of the requested obstacle. + * @returns A pointer to the corresponding Obstacle instance. + * @throws ObstacleSetException if the index, i, is invalid. + */ + virtual Obstacle * getObstacle( size_t i ) = 0; + + /*! + * @brief Sets the class of this obstacle set. + * + * @param cl the class id to which the obstacle set belongs. + */ + virtual void setClass( size_t cl) { _class = cl; }; + + /*! + * @brief Gets the class of this obstacle set. + * + * @returns The class id to which the obstacle set belongs. + */ + virtual size_t getClass() { return _class; }; + + protected: + + /*! + * @brief The class for the obstacles in this set. + * + * This works with the BaseAgent::_obstacleSet member + * to determine which obstacles affect an agent. + */ + size_t _class; + }; + + } // namespace Agents +} // namespace Menge +#endif // __OBSTACLE_SET_H__ diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.cpp new file mode 100644 index 00000000..9b53d48d --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.cpp @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSetDatabase.h" +#include "ExplicitObstacleSet.h" +#include "NavMeshObstacleSet.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< Agents::ObstacleSetFactory, Agents::ObstacleSet >::getElementName() { return "obstacle set"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< Agents::ObstacleSetFactory, Agents::ObstacleSet >::addBuiltins() { + addFactory( new Agents::ExplicitObstacleSetFactory() ); + addFactory( new Agents::NavMeshObstacleSetFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.h b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.h new file mode 100644 index 00000000..4ee033d6 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetDatabase.h @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ObstacleSetDatabase.h + * @brief Central database for querying available obstacle set implementations. + * + * For obstacle sets to be used in simulation, they must register + * themselves into the ObstacleSetDB. This is done via the PluginEngine. + */ + +#ifndef __OBSTACLE_SET_DATABASE_H__ +#define __OBSTACLE_SET_DATABASE_H__ + +#include "ElementDatabase.h" +#include "ObstacleSets/ObstacleSetFactory.h" +#include "ObstacleSets/ObstacleSet.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered aobstacle set implementations. + */ + typedef ElementDB< ObstacleSetFactory, ObstacleSet > ObstacleSetDB; + + } // namespace Agents + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + // Declarations of explicit specialization + template<> void ElementDB< Agents::ObstacleSetFactory, Agents::ObstacleSet >::addBuiltins(); + template<> std::string ElementDB< Agents::ObstacleSetFactory, Agents::ObstacleSet >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __OBSTACLE_SET_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.cpp b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.cpp new file mode 100644 index 00000000..a88e1a88 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.cpp @@ -0,0 +1,63 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleSetFactory.h" +#include "tinyxml.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ObstacleSetFactory + ///////////////////////////////////////////////////////////////////// + + ObstacleSetFactory::ObstacleSetFactory() : ElementFactory(), _classID(0) { + _classID = _attrSet.addSizeTAttribute("class",true); + } + + bool ObstacleSetFactory::setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< ObstacleSet >::setFromXML( gen, node, behaveFldr ) ) return false; + + gen->_class = _attrSet.getSizeT(_classID); + + return true; + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.h b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.h new file mode 100644 index 00000000..252f479a --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleSetFactory.h @@ -0,0 +1,97 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ObstacleSetFactory.h + * @brief The factory for parsing xml data and instantiating + * ObstacleSet implementations. + */ + +#ifndef __OBSTACLE_SET_FACTORY_H__ +#define __OBSTACLE_SET_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "ObstacleSets/ObstacleSet.h" + +namespace Menge { + + namespace Agents { + + /*! + * @brief A class for parsing the xml description of an agent generator + * and instantiating particular instances. + */ + class MENGE_API ObstacleSetFactory : public ElementFactory< ObstacleSet > { + public: + /* + * @brief default constructor + */ + ObstacleSetFactory(); + + protected: + /*! + * @brief Given a pointer to an ObstacleSet instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this ObstacleSet's type. + * (i.e. ObstacleSetFactory::thisFactory has already been called and returned true.) + * If sub-classes of ObstacleSetFactory introduce *new* ObstacleSet parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param gen A pointer to the ObstacleSet whose attributes are to be set. + * @param node The XML node containing the ObstacleSet attributes. + * @param behaveFldr The path to the behavior file. If the ObstacleSet references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( ObstacleSet * gen, TiXmlElement * node, const std::string & behaveFldr ) const; + + + /*! + * @brief The identifier for the "class" size_t parameter. + */ + size_t _classID; + }; + } // namespace Agents +} // namespace Menge + +#endif //__OBSTACLE_SET_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleVertexList.h b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleVertexList.h new file mode 100644 index 00000000..a7780ffe --- /dev/null +++ b/src/Menge/MengeCore/Agents/ObstacleSets/ObstacleVertexList.h @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ObstacleVertexList.h + * @brief The definition of the set of vertices for an explicit obstacle definition. + */ + +#ifndef __OBSTACLE_VERTEX_LIST__ +#define __OBSTACLE_VERTEX_LIST__ + +#include +#include "mengeCommon.h" + +namespace Menge { + + /*! + * @file ObstacleVertexList.h + * @brief defines a struct for passing around obstacles as lists of vertex and a closed flag + */ + namespace Agents { + /*! + * @brief A strcuture for passing vertices and closed tags for obstacles + */ + struct ObstacleVertexList { + /*! + * @brief The list of vertices for the obstacle. + */ + std::vector vertices; + + /*! + * @brief Indicates if the obstacle is closed (true) or open (false). + */ + bool closed; + }; + } // namespace Agents +} // namespace Menge + +#endif diff --git a/src/Menge/MengeCore/Agents/PrefVelocity.cpp b/src/Menge/MengeCore/Agents/PrefVelocity.cpp new file mode 100644 index 00000000..e95b7bdb --- /dev/null +++ b/src/Menge/MengeCore/Agents/PrefVelocity.cpp @@ -0,0 +1,99 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PrefVelocity.h" +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////// + // Implementation of PrefVelocity + //////////////////////////////////////////////////////////////// + + PrefVelocity::PrefVelocity(): _left(1.f,0.f), _right(1.f,0.f), _speed(1.f), _preferred(1.f,0.f), _target(0.f,0.f) {} + + //////////////////////////////////////////////////////////////// + + PrefVelocity::PrefVelocity( const Vector2 & dir, float speed, const Vector2 & target ):_left(dir), _right(dir), _speed(speed), _preferred(dir), _target(target) { + } + + //////////////////////////////////////////////////////////////// + + PrefVelocity::PrefVelocity( const Vector2 & left, const Vector2 & right, const Vector2 & pref, float speed, const Vector2 & target ): _left(left), _right(right), _speed(speed), _preferred(pref), _target(target) { + } + + //////////////////////////////////////////////////////////////// + + PrefVelocity::PrefVelocity( const PrefVelocity & vel ): _left(vel._left), _right(vel._right), _speed(vel._speed), _preferred(vel._preferred), _target(vel._target) { + } + + //////////////////////////////////////////////////////////////// + + PrefVelocity & PrefVelocity::operator=( const PrefVelocity & vel ) { + // NOTE: + // This doesn't include the typical if ( this != &vel ) test. + // The reason for this is, it is considered highly unlikely that the user will + // ever do a = a (even indirectly), and, as such, it is deemed better to simply + // perform the copying cost instead of incurring the test for EVERY + // other event. + _left = vel._left; + _right = vel._right; + _speed = vel._speed; + _preferred = vel._preferred; + _target = vel._target; + return (*this); + } + + //////////////////////////////////////////////////////////////// + + void PrefVelocity::setSpan( const Vector2 & left, const Vector2 & right, const Vector2 & preferred ) { + _left = left; + _right = right; + _preferred = preferred; + #if _DEBUG + const float SPAN_EPS = -1.e-4f; + #endif + assert( det( right, left ) >= SPAN_EPS ); + assert( det( right, preferred )>= SPAN_EPS ); + assert( det( preferred, left ) >= SPAN_EPS ); + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/PrefVelocity.h b/src/Menge/MengeCore/Agents/PrefVelocity.h new file mode 100644 index 00000000..eb989b0c --- /dev/null +++ b/src/Menge/MengeCore/Agents/PrefVelocity.h @@ -0,0 +1,232 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PrefVelocity.h + * @brief The definition of a preferred velocity. + */ + +#ifndef __PREF_VELOCITY_H__ +#define __PREF_VELOCITY_H__ + +#include "mengeCommon.h" + +namespace Menge { + + namespace Agents { + + /*! + * @brief The definition of a preferred velocity. + * + * The preferred velocity is actually a space of velocities defined + * by two things: + * - a preferred speed + * - a *span* of directions. + * The span of directions represents a contiguous set of directions which + * can be considered topologically equivalent with respect to the agent + * reaching its goal. + * + * For example, the shortest path may require an agent to pass down a hall way, + * but whether the agent walks down the left, middle, or side is irrelevant -- all + * three will get the agent to its final goal with negligible difference. + */ + class MENGE_API PrefVelocity { + public: + /*! + * @brief Default constructor + */ + PrefVelocity(); + + /*! + * @brief Constructor for setting a span of a single direction. + * + * @param dir The single direction. + * @param speed The preferred speed. + * @param target The target point from which the preferred direction arises. + */ + PrefVelocity( const Vector2 & dir, float speed, const Vector2 & target ); + + /*! + * @brief Constructor for setting a full span. + * + * @param left The "left"-most extent of the span (see _left). + * @param right The "right"-most extent of the span (see _right). + * @param pref The preferred direction (see _preferred). + * @param speed The preferred speed. + * @param target The target point from which the preferred direction arises. + */ + PrefVelocity( const Vector2 & left, const Vector2 & right, const Vector2 & pref, float speed, const Vector2 & target ); + + /*! + * @brief Copy constructor. + * + * @param vel An instance of preferred velocity. + */ + PrefVelocity( const PrefVelocity & vel ); + + /*! + * @brief Assignment operator + * + * @param vel Another instance of PrefVelocity whose values will be copied into this. + * @returns A reference to this preferred velocity. + */ + PrefVelocity & operator=( const PrefVelocity & vel ); + + /*! + * @brief Returns the left extent of the span. + * + * @returns The left extent. + */ + inline Vector2 getLeft() const { return _left; } + + /*! + * @brief Returns the right extent of the span. + * + * @returns The right extent. + */ + inline Vector2 getRight() const { return _right; } + + /*! + * @brief Returns the preferred *direction* of the span. + * + * @returns The preferred direction. + */ + inline Vector2 getPreferred() const { return _preferred; } + + /*! + * @brief Returns the preferred *velocity" of the span. + * This is the preferred direction at the velocity's speed. + * + * @returns A vector pointing in the preferred direction at the + * given speed. + */ + inline Vector2 getPreferredVel() const { return _preferred * _speed; } + + /*! + * @brief Returns the speed of the preferred velocity. + * + * @returns The speed of the preferred velocity. + */ + inline float getSpeed() const { return _speed; } + + /*! + * @brief Sets the speed. + * + * @param speed The speed. + */ + inline void setSpeed( float speed ) { _speed = speed; } + + /*! + * @brief Sets the preferred velocity to be a single velocity. + * + * @param dir The single preferred direction. + */ + inline void setSingle( const Vector2 & dir ) { _left = _preferred = _right = dir; } + + /*! + * @brief Gets the target of the preferred velocity. + * + * @returns A singe point in space which corresponds to the preferred direction. + */ + inline Vector2 getTarget() const { return _target; } + + /*! + * @brief Sets the target of the preferred velocity. + * + * @param target The preferred velocity's target. + */ + inline void setTarget( const Vector2 & target ) { _target = target; } + + /*! + * @brief Sets the preferred velocity span. + * + * @param left The direction of the left-most extent of the arc. + * @param right The direction of the right-most extent of the arc. + * @param preferred The single most-preferred direction in the span. + */ + void setSpan( const Vector2 & left, const Vector2 & right, const Vector2 & preferred ); + + /*! + * @brief Reports if the arc spans more than a single direction (by reporting + * whether the arc has area.) + * + * @returns A boolean indicating if the span has area (i.e. spans + * more than a single direction. + */ + inline bool hasArea() const { return _left * _right < 1.f; } + + protected: + /*! + * @brief The "left" extent of the preferred velocity span + * (i.e. det( right, left ) >= 0). This direction has + * unit length. + */ + Vector2 _left; + + /*! + * @brief The "right" extent of the preferred velocity span + * (i.e. det( right, left ) >= 0). This direction has + * unit length. + */ + Vector2 _right; + + /*! + * @brief The preferred speed (also the radius of the arc. + */ + float _speed; + + /*! + * @brief The preferred direction. All directions in the span + * may be topologically equivalent, but this direction is + * the "best". This value must lie within the span + * (i.e., det( right, preferred ) > 0 and det( preferred, left) > 0). + */ + Vector2 _preferred; + + /*! + * @brief The immediate goal point -- this corresponds to the preferred + * direction. + */ + Vector2 _target; + + }; + + } // namespace Agents +} // namespace Menge + +#endif // __PREF_VELOCITY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.cpp b/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.cpp new file mode 100644 index 00000000..b71fda53 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.cpp @@ -0,0 +1,88 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ConstProfileSelector.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ConstProfileSelector + //////////////////////////////////////////////////////////////////////////// + + ConstProfileSelector::ConstProfileSelector() : ProfileSelector(), _profileName(""), _init(0x0) { + } + + //////////////////////////////////////////////////////////////////////////// + + bool ConstProfileSelector::cacheProfiles( HASH_MAP< std::string, AgentInitializer * > profiles ) { + HASH_MAP< std::string, AgentInitializer * >::iterator itr = profiles.find( _profileName ); + if ( itr != profiles.end() ) { + _init = itr->second; + } else { + logger << Logger::ERR_MSG << "Const profile selector unable to find profile of the name " << _profileName << "\n"; + return false; + } + return true; + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ConstProfileSelectorFactory + //////////////////////////////////////////////////////////////////////////// + + ConstProfileSelectorFactory::ConstProfileSelectorFactory() : ProfileSelectorFactory() { + _nameID = _attrSet.addStringAttribute( "name", true, "" ); + } + + //////////////////////////////////////////////////////////////////////////// + + bool ConstProfileSelectorFactory::setFromXML( ProfileSelector * pSel, TiXmlElement * node, const std::string & specFldr ) const { + ConstProfileSelector * cSel = dynamic_cast< ConstProfileSelector * >( pSel ); + assert( cSel != 0x0 && "Trying to set attributes of a const profile selector element on an incompatible object" ); + + if ( ! ProfileSelectorFactory::setFromXML( cSel, node, specFldr ) ) return false; + + cSel->setName( _attrSet.getString( _nameID ) ); + + return true; + } + + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.h b/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.h new file mode 100644 index 00000000..eb637b87 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ConstProfileSelector.h @@ -0,0 +1,180 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ConstProfileSelector.h + * @brief The definition of a profile selector that assigns all agents + * the same profile. + */ + +#ifndef __CONST_PROFILE_SELECTOR_H__ +#define __CONST_PROFILE_SELECTOR_H__ + +#include "mengeCommon.h" +#include "ProfileSelectors/ProfileSelector.h" +#include "ProfileSelectors/ProfileSelectorFactory.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief A profile selector that stores a single agent initializer + * and assigns this profile to all agents. + */ + class MENGE_API ConstProfileSelector : public ProfileSelector { + public: + /*! + * @brief Constructor. + */ + ConstProfileSelector(); + + /*! + * @brief Select an agent profile based on internal mechanisms. + * + * @returns A const pointer to an agent initializer. + */ + virtual AgentInitializer * getProfile() const { return _init; } + + /*! + * @brief Caches the agent initializers defined in the specification. + * + * Although the ProfileSelector can cache pointers to the profiles for + * internal convenience, it does not own the memory and should not delete + * them. + * + * @param profiles A mapping from profile name to initializer. + * @returns True if successful, false otherwise. + */ + virtual bool cacheProfiles( HASH_MAP< std::string, AgentInitializer * > profiles ); + + /*! + * @brief Sets the name of the profile. + * + * @param name The name of the selector's profile. + */ + void setName( const std::string & name ) { _profileName = name; } + + protected: + /*! + * @brief The name of the profile to use. + */ + std::string _profileName; + + /*! + * @brief The initializer belonging to the named profile + */ + AgentInitializer * _init; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for the ConstProfileSelector. + */ + class MENGE_API ConstProfileSelectorFactory : public ProfileSelectorFactory { + public: + /*! + * @brief Constructor + */ + ConstProfileSelectorFactory(); + + /*! + * @brief The name of the profile selector type. + * + * The profile selector's name must be unique among all registered profile selector elements. + * Each profile selector factory must override this function. + * + * @returns A string containing the unique profile selector name. + */ + virtual const char * name() const { return "const"; } + + /*! + * @brief A description of the profile selector. + * + * Each profile selector factory must override this function. + * + * @returns A string containing the profile selector description. + */ + virtual const char * description() const { + return "Profile selector which assigns the same profile to all agents."; + }; + + protected: + /*! + * @brief Create an instance of this class's profile selector implementation. + * + * All ProfileSelectorFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding selector type. The various field values + * of the instance will be set in a subsequent call to ProfileSelectorFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated ProfileSelector class. + */ + ProfileSelector * instance() const { return new ConstProfileSelector(); } + + /*! + * @brief Given a pointer to a pProfileSelector instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this ProfileSelector's type. + * (i.e. ProfileSelectorFactory::thisFactory has already been called and returned true.) + * If sub-classes of ProfileSelectorFactory introduce *new* ProfileSelector parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param pSel A pointer to the profile selector whose attributes are to be set. + * @param node The XML node containing the goal attributes. + * @param specFldr The path to the specification file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( ProfileSelector * pSel, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "name" string parameter. + */ + size_t _nameID; + + + }; + + } // namespace Agents +} // namespace Menge +#endif // __CONST_PROFILE_SELECTOR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.cpp b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.cpp new file mode 100644 index 00000000..4e093281 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.cpp @@ -0,0 +1,58 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ProfileSelectors/ProfileSelector.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ProfileSelector + ///////////////////////////////////////////////////////////////////// + + ProfileSelector::ProfileSelector(): Element() { + } + + ///////////////////////////////////////////////////////////////////// + + ProfileSelector::~ProfileSelector() { + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.h b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.h new file mode 100644 index 00000000..aaf85f3d --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelector.h @@ -0,0 +1,136 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ProfileSelector.h + * @brief The definition of the agent profile selector element. + * This is the mechanism which associates an agent profile with a new agent. + */ +#ifndef __PROFILE_SELECTOR_H__ +#define __PROFILE_SELECTOR_H__ + +#include "mengeCommon.h" +#include "Element.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class BaseAgent; + class AgentInitializer; + + /*! + * @brief Exception class for profile selector computation. + */ + class MENGE_API ProfileSelectorException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + ProfileSelectorException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ProfileSelectorException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal profile selector exception. + */ + class MENGE_API ProfileSelectorFatalException : public ProfileSelectorException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + ProfileSelectorFatalException() : MengeException(), ProfileSelectorException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ProfileSelectorFatalException( const std::string & s ): MengeException(s), ProfileSelectorException(), MengeFatalException() {} + }; + + + /*! + * @brief The base class for agent profile assignment strategies. + * + * This is an abstract class, primarily defining the mechanism for selecting + * an agent profile to assign to a newly created agent. + */ + class MENGE_API ProfileSelector : public Element { + public: + /*! + * @brief Constructor + */ + ProfileSelector(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~ProfileSelector(); + + public: + /*! + * @brief Select an agent profile based on internal mechanisms. + * + * @returns A const pointer to an agent initializer. + */ + virtual AgentInitializer * getProfile() const = 0; + + /*! + * @brief Caches the agent initializers defined in the specification. + * + * Although the ProfileSelector can cache pointers to the profiles for + * internal convenience, it does not own the memory and should not delete + * them. + * + * @param profiles A mapping from profile name to initializer. + * @returns True if successful, false otherwise. + */ + virtual bool cacheProfiles( HASH_MAP< std::string, AgentInitializer * > profiles ) = 0; + }; + + } // namespace Agents +} // namespace Menge +#endif // __PROFILE_SELECTOR_H__ diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.cpp b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.cpp new file mode 100644 index 00000000..5e78e486 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ProfileSelectorDatabase.h" +#include "ProfileSelectors/ConstProfileSelector.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< Agents::ProfileSelectorFactory, Agents::ProfileSelector >::getElementName() { return "profile selector"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< Agents::ProfileSelectorFactory, Agents::ProfileSelector >::addBuiltins() { + addFactory( new Agents::ConstProfileSelectorFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.h b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.h new file mode 100644 index 00000000..b1a89d0a --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorDatabase.h @@ -0,0 +1,71 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ProfileSelectorDatabase.h + * @brief Central database for querying available profile selector implementations. + * + * For profile selectors to be used in simulation, they must register + * themselves into the ProfileSelectorDatabase. This is done via the PluginEngine. + */ + +#ifndef __PROFILE_SELECTOR_DATABASE_H__ +#define __PROFILE_SELECTOR_DATABASE_H__ + +#include "ElementDatabase.h" +#include "ProfileSelectors/ProfileSelectorFactory.h" +#include "ProfileSelectors/ProfileSelector.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered profile selector implementations. + */ + typedef ElementDB< ProfileSelectorFactory, ProfileSelector > ProfileSelectorDB; + + } // namespace Agents + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< Agents::ProfileSelectorFactory, Agents::ProfileSelector >::addBuiltins(); + template<> std::string ElementDB< Agents::ProfileSelectorFactory, Agents::ProfileSelector >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS +} // namespace Menge +#endif // __PROFILE_SELECTOR_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorFactory.h b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorFactory.h new file mode 100644 index 00000000..b66d2978 --- /dev/null +++ b/src/Menge/MengeCore/Agents/ProfileSelectors/ProfileSelectorFactory.h @@ -0,0 +1,63 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ProfileSelectorFactory.h + * @brief The factory for parsing xml data and instantiating + * profile selector implementations. + */ + +#ifndef __PROFILE_SELECTOR_FACTORY_H__ +#define __PROFILE_SELECTOR_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "ProfileSelectors/ProfileSelector.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief A class for parsing the xml description of an agent profile selector elements + * and instantiating particular instances. + */ + class MENGE_API ProfileSelectorFactory : public ElementFactory< ProfileSelector > { + }; + } // namespace Agents +} // namespace Menge +#endif // __PROFILE_SELECTOR_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SCBWriter.cpp b/src/Menge/MengeCore/Agents/SCBWriter.cpp new file mode 100644 index 00000000..1277f482 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SCBWriter.cpp @@ -0,0 +1,260 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SCBWriter.h" +#include "SimulatorInterface.h" +#include "Core.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBWriter + ///////////////////////////////////////////////////////////////////// + + SCBWriter::SCBWriter( const std::string & pathName, const std::string & version, SimulatorInterface * sim ):_frameWriter(0x0) { + if ( !validateVersion( version ) ) { + logger << Logger::ERR_MSG << "Invalid SCB version: " << version << "\n"; + throw SCBVersionException(); + } + logger << Logger::INFO_MSG << "SCBWRITER: version: " << _version[0] << "." << _version[1] << "\n"; + _file.open( pathName.c_str(), std::ios::out | std::ios::binary ); + if ( ! _file.is_open() ) { + throw SCBFileException(); + } + _sim = sim; + writeHeader(); + } + + ///////////////////////////////////////////////////////////////////// + + SCBWriter::~SCBWriter() { + if ( _file.is_open() ) _file.close(); + if ( _frameWriter ) delete _frameWriter; + } + + ///////////////////////////////////////////////////////////////////// + + bool SCBWriter::validateVersion( const std::string & version ) { + bool valid = ( version == "1.0" || // a simple exhaustive list of valid versions + version == "2.0" || + version == "2.1" || + version == "2.2" || + version == "2.3" || + version == "2.4" ); + if ( valid ) { + // convert string to ints + size_t dotPos = version.find_first_of( "." ); + _version[0] = atoi( version.substr( 0, dotPos ).c_str() ); + _version[1] = atoi( version.substr( dotPos + 1 ).c_str() ); + if ( _version[0] == 1 && _version[1] == 0 ) { + _frameWriter = new SCBFrameWriter1_0(); + } else if ( _version[0] == 2 ) { + if ( _version[1] == 0 ) { + _frameWriter = new SCBFrameWriter2_0(); + } else if ( _version[1] == 1 ) { + _frameWriter = new SCBFrameWriter2_1(); + } else if ( _version[1] == 2 ) { + _frameWriter = new SCBFrameWriter2_2(); + } else if ( _version[1] == 3 ) { + _frameWriter = new SCBFrameWriter2_3(); + } else if ( _version[1] == 4 ) { + _frameWriter = new SCBFrameWriter2_4(); + } + } + assert( _frameWriter != 0x0 && "Valid version didn't produce a frame writer" ); + } + return valid; + } + + ///////////////////////////////////////////////////////////////////// + + void SCBWriter::writeFrame( BFSM::FSM * fsm ) { + _frameWriter->writeFrame( _file, _sim, fsm ); + } + + ///////////////////////////////////////////////////////////////////// + + void SCBWriter::writeHeader() { + _file << _version[0] << "." << _version[1] << (char)0x0; + if ( _version[0] == 1 ) { + writeHeader1_0(); + } else if ( _version[ 0 ] == 2 ) { + writeHeader2_0(); + } + } + + ///////////////////////////////////////////////////////////////////// + + void SCBWriter::writeHeader1_0() { + const size_t AGT_COUNT = _sim->getNumAgents(); + _file.write( (char*)&AGT_COUNT, sizeof(int) ); + } + + ///////////////////////////////////////////////////////////////////// + + void SCBWriter::writeHeader2_0() { + const size_t AGT_COUNT = _sim->getNumAgents(); + _file.write( (char*)&AGT_COUNT, sizeof(int) ); + float step = _sim->getTimeStep(); + _file.write( (char*)&step, sizeof( float ) ); + // write ids + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = _sim->getAgent( i ); + unsigned int cID = static_cast< unsigned int >( agt->_class ); + _file.write( (char*)&cID, sizeof(unsigned int) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter + ///////////////////////////////////////////////////////////////////// + + const int SCBFrameWriter::ZERO = 0; + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter1_0 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter1_0::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + file.write( (char*)&p, 2 * sizeof(float) ); + float orient = atan2( agt->_orient.y(), agt->_orient.x() ); + file.write( (char*)&orient, sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter2_0 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter2_0::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + file.write( (char*)&p, 2 * sizeof(float) ); + float orient = atan2( agt->_orient.y(), agt->_orient.x() ); + file.write( (char*)&orient, sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter2_1 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter2_1::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + file.write( (char*)&p, 2 * sizeof(float) ); + float orient = atan2( agt->_orient.y(), agt->_orient.x() ); + file.write( (char*)&orient, sizeof(float) ); + float state = (float)fsm->getAgentStateID( i ); + file.write( (char*)&state, sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter2_2 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter2_2::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + file.write( (char*)&p, 2 * sizeof(float) ); + float orient = atan2( agt->_orient.y(), agt->_orient.x() ); + file.write( (char*)&orient, sizeof(float) ); + float state = (float)fsm->getAgentStateID( i ); + file.write( (char*)&state, sizeof(float) ); + // pref velocity + // NOTE: This does not use _velPref.getSpeed() because it may be modified + // by intention filters. This factors those out. + const Vector2 vDir = agt->_velPref.getPreferredVel(); + file.write( (char*)&vDir, 2 * sizeof(float) ); + // velocity + const Vector2 & v = agt->_vel; + file.write( (char*)&v, 2 * sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter2_3 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter2_3::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + file.write( (char*)&p, 2 * sizeof(float) ); + file.write( (char*)&agt->_orient, 2 * sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriter2_4 + ///////////////////////////////////////////////////////////////////// + + void SCBFrameWriter2_4::writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) { + const size_t AGT_COUNT = sim->getNumAgents(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Agents::BaseAgent * agt = sim->getAgent( i ); + const Vector2 & p = agt->_pos; + float elevation = sim->getElevation( agt ); + file.write( (char*)&p._x, sizeof(float) ); + file.write( (char*)&elevation, sizeof(float) ); + file.write( (char*)&p._y, sizeof(float) ); + float orient = atan2( agt->_orient.y(), agt->_orient.x() ); + file.write( (char*)&orient, sizeof(float) ); + } + } + + ///////////////////////////////////////////////////////////////////// + + + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SCBWriter.h b/src/Menge/MengeCore/Agents/SCBWriter.h new file mode 100644 index 00000000..b4c78592 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SCBWriter.h @@ -0,0 +1,350 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SCBWriter.h + * @brief Functionality for writing the crowd trajectories to a binary file. + */ + +#ifndef __SCB_WRITER_H__ +#define __SCB_WRITER_H__ + +#include +#include +#include "mengeCommon.h" +#include "FSM.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Base exception class for scb writers + */ + class MENGE_API SCBException : public virtual Menge::MengeException { + public: + /*! + * @brief Default constructor. + */ + SCBException() : Menge::MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SCBException( const std::string & s ): Menge::MengeException(s) {} + }; + + /*! + * @brief The fatal scb writers exception. + */ + class MENGE_API SCBFatalException : public SCBException, public Menge::MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + SCBFatalException() : Menge::MengeException(), SCBException(), Menge::MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SCBFatalException( const std::string & s ): Menge::MengeException(s), SCBException(), Menge::MengeFatalException() {} + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Exception raised for invalid scb version. + */ + class MENGE_API SCBVersionException : public SCBFatalException { + public: + /*! + * @brief Default constructor. + */ + SCBVersionException() : SCBFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SCBVersionException( const std::string & s ): SCBFatalException(s) {} + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Exception raised for file I/O errors + */ + class MENGE_API SCBFileException : public SCBException { + public: + /*! + * @brief Default constructor. + */ + SCBFileException() : SCBException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SCBFileException( const std::string & s ): SCBException(s) {} + }; + + // Forward declaration + class SCBFrameWriter; + class SimulatorInterface; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Class responsible for writing the agent state of the simulator and + * fsm into a file. + */ + class SCBWriter { + public: + /*! + * @brief Constructor for SCBWriter + * + * @param pathName The path for the desired output file. + * @param version A string representing the version to write out. + * @param sim A pointer to the simulator to process + * @throws SCBVersionException If the version string is not considered to be + * a valid version. + * @throws SCBFileException If there is a problem opening the given path + * for writing. + */ + SCBWriter( const std::string & pathName, const std::string & version, SimulatorInterface * sim ); + + /*! + * @brief Destructor. + */ + ~SCBWriter(); + + /*! + * @brief Writes the current frame of the stored simulator to the file. + * + * @param fsm A pointer to the simulator's fsm + */ + void writeFrame( BFSM::FSM * fsm ); + + protected: + /*! + * @brief The frame writer -- defines the format of the frame's data. + */ + SCBFrameWriter * _frameWriter; + + /*! + * @brief The version of the scb file to be written. + * Version is represented by the integer _verstion[0]._version[1] + */ + int _version[2]; + + /*! + * @brief A pointer to the simulator to write to the file + */ + SimulatorInterface * _sim; + + /*! + * @brief The file object for the scb stream to be written to. + */ + std::ofstream _file; + + /*! + * @brief Confirms that the given version is valid. + * Function has side-effects. This must be called for the SCBWriter to work. + * + * @param version A string of the format "major"."minor" (e.g., 2.1) + * for the desired output format. + * @returns A boolean reporting if the version is valid (true) or invalid (false). + */ + bool validateVersion( const std::string & version ); + + /*! + * @brief Writes the appropriate header to the open file. + */ + void writeHeader(); + + /*! + * @brief Writes the header appropriate to major version 1 formats. + */ + void writeHeader1_0(); + + /*! + * @brief Writes the header appropriate to major version 2 formats. + */ + void writeHeader2_0(); + }; + + ///////////////////////////////////////////////////////////////////// + // Implementation of SCBFrameWriters + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief This base class for writing a single frame of simulation data + * to the scb file. + */ + class SCBFrameWriter { + public: + /*! + * @brief Simple static variable for writing binary zeros to the file. + */ + static const int ZERO; + + /*! + * @brief Function to write current frame's state to the file. + * + * @param file The file object to write to. + * @param sim A pointer to the simulator. + * @param fsm A pointer to the behavior fsm for the simulator. + */ + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ) = 0; + }; + + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 1.0 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos + * 4-byte float orientation (radians) + */ + class SCBFrameWriter1_0 : public SCBFrameWriter{ + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 2.0 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos + * 4-byte float orientation (radians) + */ + class SCBFrameWriter2_0 : public SCBFrameWriter { + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 2.1 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos + * 4-byte float orientation (radians) + * 4-byte float stateID - although stored as a float, the value will be + * an integer value. + */ + class SCBFrameWriter2_1 : public SCBFrameWriter { + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 2.2 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos + * 4-byte float orientation (radians) + * 4-byte float stateID - although stored as a float, the value will be + * an integer value. + * 4-byte float x-vPref (the x-component of the agent's preferred velocity). + * 4-byte float y-vPref (the y-component of the agent's preferred velocity). + * 4-byte float x-vel (the x-component of the agent's current velocity). + * 4-byte float y-vel (the y-component of the agent's current velocity). + */ + class SCBFrameWriter2_2 : public SCBFrameWriter { + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 2.3 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos + * 4-byte float x-direction - the x-component of the unit vector + * pointing in the direction of orientation. + * 4-byte float y-direction - the y-component of the unit vector + * pointing in the direction of orientation. + */ + class SCBFrameWriter2_3 : public SCBFrameWriter { + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Writer for version 2.4 + * + * The data for an agent consists of: + * 4-byte float x-pos + * 4-byte float y-pos (elevation) + * 4-byte float z-pos + * 4-byte float orientation (radians) + */ + class SCBFrameWriter2_4 : public SCBFrameWriter { + public: + virtual void writeFrame( std::ofstream & file, SimulatorInterface * sim, BFSM::FSM * fsm ); + }; + + } // namespace Agents +} // namespace Menge +#endif // __SCB_WRITER_H__ diff --git a/src/Menge/MengeCore/Agents/SimXMLLoader.cpp b/src/Menge/MengeCore/Agents/SimXMLLoader.cpp new file mode 100644 index 00000000..3271558e --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimXMLLoader.cpp @@ -0,0 +1,373 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimXMLLoader.h" +#include "XMLSimulatorBase.h" +#include +#include +#include +#include "BaseAgent.h" +#include "SimulatorState.h" +#include "Elevations/ElevationDatabase.h" +#include "SpatialQueries/SpatialQueryDatabase.h" +#include "AgentGenerators/AgentGeneratorDatabase.h" +#include "ProfileSelectors/ProfileSelectorDatabase.h" +#include "StateSelectors/StateSelectorDatabase.h" +#include "ObstacleSets/ObstacleSetDatabase.h" +#include "AgentInitializer.h" +#include "os.h" +#include "Core.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////// + // Implementation of SimXMLLoader + //////////////////////////////////////////////////////////////////// + + SimXMLLoader::SimXMLLoader( XMLSimulatorBase * sim ):_sceneFldr("."),_sim(sim), _agtCount(0) { + } + + //////////////////////////////////////////////////////////////////// + + bool SimXMLLoader::loadFromXML( const std::string & filename, AgentInitializer * agentInit, bool verbose ) { + // COnfirms file is + // a) available for reading + // b) valid xml + // c) An "Experiment" + if ( verbose ) logger << Logger::INFO_MSG << "Loading from xml: " << filename << "."; + TiXmlDocument xml( filename ); + bool loadOkay = xml.LoadFile(); + + if ( !loadOkay ) { // load xml file + logger << Logger::ERR_MSG << "Could not load simulation configuration xml (" << filename << ") due to xml syntax errors.\n"; + logger << "\t" << xml.ErrorDesc(); + return false; + } + + TiXmlElement* experimentNode = xml.RootElement(); + if( ! experimentNode ) { + logger << Logger::ERR_MSG << "Scene configuration (" << filename << ") does not contain a root element."; + return false; + } + + if( experimentNode->ValueStr () != "Experiment" ) { + logger << Logger::ERR_MSG << "Scene configuration (" << filename << ")'s root element is not \"Experiment\"."; + return false; + } + + std::string absPath; + os::path::absPath( filename, absPath ); + std::string junk; + os::path::split( absPath, _sceneFldr, junk ); + logger << Logger::INFO_MSG << "Scene root: " << _sceneFldr << "."; + + bool commonDone = false; // common experiment parameters parsed + bool targetDone = !_sim->hasExpTarget(); // target experiment parameters parsed + bool spatialQueryDone = false; // spatial query must be finished before obstacles and agents can be created + + // Tags I'm not ready to parse - only parse agent sets and obstacles AFTER experiment + // parameters + std::list< TiXmlElement * > tagQueue; + + TiXmlElement* child; + for( child = experimentNode->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "Common" ) { + // Currently the only "common" experiment parameter is the time step + TiXmlAttribute * attr; + for ( attr = child->FirstAttribute(); attr; attr = attr->Next() ) { + try { + if ( !_sim->setExpParam( attr->Name(), attr->ValueStr() ) ) { + logger << Logger::WARN_MSG << "Unrecognized parameter in the global \"Common\" parameters (" << attr->Name() << ") on line " << child->Row() << "\n"; + } + } catch ( XMLParamException e ) { + logger << Logger::ERR_MSG << e.what(); + return false; + } + } + commonDone = true; + } else if ( child->ValueStr() == "AgentProfile" ) { + if ( !parseAgentProfile( child, agentInit ) ) { + return false; + } + } else if ( child->ValueStr() == "AgentGroup" ) { + if ( ! ( commonDone || targetDone || spatialQueryDone ) ) { + tagQueue.push_back( child ); + } else { + if ( !parseAgentGroup( child, agentInit ) ) { + return false; + } + } + } else if ( child->ValueStr() == "ObstacleSet" ) { + if ( ! ( commonDone || targetDone || spatialQueryDone) ) { + tagQueue.push_back( child ); + } else { + if ( ! parseObstacleSet( child ) ) { + return false; + } + } + } else if ( child->ValueStr() == "Elevation" ) { + if ( _sim->hasElevation() ) { + logger << Logger::ERR_MSG << "More than one elevation has been specified. Found redundant elevation specification on line " << child->Row() << "."; + return false; + } + Elevation * elevation = ElevationDB::getInstance( child, _sceneFldr ); + if ( elevation == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate elevation specifcation on line " << child->Row() << "."; + return false; + } else { + _sim->setElevationInstance( elevation ); + } + Menge::ELEVATION = elevation; + } else if ( child->ValueStr() == "SpatialQuery" ) { + if ( _sim->hasSpatialQuery() ) { + logger << Logger::ERR_MSG << "More than one spatial query implementation has been specified. Found redundant spatial query specification on line " << child->Row() << "."; + return false; + } + SpatialQuery * spQuery = SpatialQueryDB::getInstance( child, _sceneFldr ); + if ( spQuery == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate spatial query specifcation on line " << child->Row() << "."; + return false; + } else { + _sim->setSpatialQuery( spQuery ); + spatialQueryDone = true; + } + } else { // target parameter + if ( !targetDone && _sim->isExpTarget( child->ValueStr() ) ) { + // Parse the target + TiXmlAttribute * attr; + for ( attr = child->FirstAttribute(); attr; attr = attr->Next() ) { + try { + if ( ! _sim->setExpParam( attr->Name(), attr->ValueStr() ) ) { + logger << Logger::WARN_MSG << "Unrecognized parameter in the global \"" << child->ValueStr() << "\" parameters (" << attr->Name() << ") on line " << child->Row() << "\n"; + } + } catch ( XMLParamException e ) { + logger << Logger::ERR_MSG << e.what() << " (on line " << child->Row() << ")"; + return false; + } + } + targetDone = true; + } + } + } + if ( !targetDone || !commonDone || !spatialQueryDone) { + logger << Logger::ERR_MSG << "Missing required experiment parameters: \n"; + if ( !targetDone ) logger << "\tmodel simulation parameters "; + if ( !commonDone ) logger << "\tcommon simulation parameters "; + if ( !spatialQueryDone ) logger << "\tSpatial Query "; + return false; + } + // Now parse any of the tags that were skipped while waiting for experiment configuration + std::list< TiXmlElement * >::iterator tagItr = tagQueue.begin(); + for ( ; tagItr != tagQueue.end(); ++tagItr ) { + TiXmlElement * child = *tagItr; + if ( child->ValueStr() == "AgentGroup" ) { + if ( !parseAgentGroup( child, agentInit ) ) { + return false; + } + } else if ( child->ValueStr() == "ObstacleSet" ) { + if ( ! parseObstacleSet( child ) ) { + return false; + } + } else { + logger << Logger::ERR_MSG << "XML contains an invalid tag: " << child->ValueStr() << " on line " << child->Row() << "."; + return false; + } + } + + if ( _agtCount == 0 ) { + // TODO: Change this test when agent sources are introduced + // in this case, it is possible to start with no agents and then add them + // w.r.t. time. + logger << Logger::ERR_MSG << "No agents defined in simulation."; + return false; + } + + // free up the profiles + // TODO: I'll need to save these when I have AgentSources. + for ( HASH_MAP< std::string, AgentInitializer * >::iterator itr = _profiles.begin(); + itr != _profiles.end(); + ++itr ) + { + delete itr->second; + } + _profiles.clear(); + + return _sim->initSpatialQuery(); + } + + //////////////////////////////////////////////////////////////////// + + bool SimXMLLoader::parseAgentGroup( TiXmlElement * node, AgentInitializer * agentInit ) { + // 2-pass approach + // Pass 1 get the profile selector + // Pass 2 initialize AgentGenerator (Generator for short) + + // Get the profile selector - + TiXmlElement* child; + ProfileSelector * profileSel = 0x0; + StateSelector * stateSel = 0x0; + // First pass, skip Agents + for( child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "ProfileSelector" ) { + if ( profileSel != 0x0 ) { + // There should be only one. If there are multiple, only the first will have an effect. + logger << Logger::WARN_MSG << "Found multiple ProfileSelector tags in the AgentGroup on line " << node->Row() << ". Only the first will be used."; + continue; + } + profileSel = ProfileSelectorDB::getInstance( child, _sceneFldr ); + if ( profileSel == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate the profile selector specification line " << child->Row() << "."; + return false; + } + if ( ! profileSel->cacheProfiles( _profiles ) ) { + logger << Logger::ERR_MSG << "ProfileSelector on line " << child->Row() << " was unable to find a named profile."; + return false; + } + } else if ( child->ValueStr() == "StateSelector" ) { + if ( stateSel != 0x0 ) { + // There should be only one. If there are multiple, only the first will have an effect. + logger << Logger::WARN_MSG << "Found multiple StateSelector tags in the AgentGroup on line " << node->Row() << ". Only the first will be used."; + continue; + } + stateSel = StateSelectorDB::getInstance( child, _sceneFldr ); + if ( stateSel == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate the state selector specification line " << child->Row() << "."; + return false; + } + } + } + if ( profileSel == 0x0 ) { + logger << Logger::ERR_MSG << "No profile selector defined for the AgentGroup on line " << node->Row() << "."; + return false; + } + if ( stateSel == 0x0 ) { + logger << Logger::ERR_MSG << "No state selector defined for the AgentGroup on line " << node->Row() << "."; + return false; + } + + // Second pass, parse Generators + for( child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "Generator" ) { + AgentGenerator * generator = AgentGeneratorDB::getInstance( child, _sceneFldr ); + + if ( generator == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate agent generator specifcation on line " << child->Row() << "."; + return false; + } + // Now instantiate the agents + const size_t AGT_COUNT = generator->agentCount(); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + Vector2 p = generator->agentPos( i ); + BaseAgent * agent = _sim->addAgent( p, profileSel->getProfile() ); + _sim->getInitialState()->setAgentState( agent->_id, stateSel->getState() ); + } + _agtCount += (unsigned int) AGT_COUNT; + + generator->destroy(); + } + } + + return true; + } + + + //////////////////////////////////////////////////////////////////// + + bool SimXMLLoader::parseObstacleSet( TiXmlElement * node) { + //pass through, try to get a generator, and then use it + ObstacleSet * obSet = ObstacleSetDB::getInstance( node, _sceneFldr ); + if ( obSet == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate obstacle set specifcation on line " << node->Row() << "."; + return false; + } else { + //_sim->setSpatialQuery( spQuery ); + size_t index = 0; + for (;index < obSet->obstacleCount();++index){ + _sim->getSpatialQuery()->addObstacle(obSet->getObstacle(index)); + } + + obSet->destroy(); + return true; + } + } + + //////////////////////////////////////////////////////////////////// + + bool SimXMLLoader::parseAgentProfile( TiXmlElement * node, AgentInitializer * agentInit ) { + // Extract the name + const char * nameCStr = node->Attribute( "name" ); + if ( nameCStr == 0x0 ) { + logger << Logger::ERR_MSG << "The AgentProfile defined on line " << node->Row() << " is missing the required \"name\" attribute."; + return false; + } + std::string name( nameCStr ); + if ( _profiles.find( name ) != _profiles.end() ) { + logger << Logger::ERR_MSG << "The AgentProfile defined on line " << node->Row() << " has a name value (\"" << name << "\")that has previously been used."; + return false; + } + + AgentInitializer * init; + // test inheritance + const char * parentCStr = node->Attribute( "inherits" ); + if ( parentCStr ) { + std::string pName( parentCStr ); + HASH_MAP< std::string, AgentInitializer * >::iterator itr = _profiles.find( pName ); + if ( itr == _profiles.end() ) { + logger << Logger::ERR_MSG << "The AgentProfile on line " << node->Row() << " inherits from the undefined AgentProfile \"" << pName << "\". Make sure the parent profile is defined before the child profile."; + return false; + } else { + init = itr->second->copy(); + } + } else { + init = agentInit->copy(); + init->setDefaults(); + } + _profiles[ name ] = init; + + for( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( ! init->parseProperties( child, _sceneFldr) ) { + logger << Logger::ERR_MSG << "Error parsing AgentProfile properties from line " << child->Row() << "."; + return false; + } + } + return true; + } + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SimXMLLoader.h b/src/Menge/MengeCore/Agents/SimXMLLoader.h new file mode 100644 index 00000000..bc28d9a5 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimXMLLoader.h @@ -0,0 +1,136 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __SIM_XML_LOADER__ +#define __SIM_XML_LOADER__ + +/*! + * @file SimXMLLoader.h + * @brief Contains functionality for parsing simulation specifcation + * from an XML file. + */ + +#include "mengeCommon.h" +#include +#include "tinyxml/tinyxml.h" + +namespace Menge { + + namespace Agents { + + // Forward declartion + class XMLSimulatorBase; + class AgentInitializer; + + /*! + * @brief Class for parsing the SCENE XML specification and initialize a simulator + * It only knows the most fundamental common aspects of the file, relying on the + * Simulator to know of its own specific domain knowledge. + */ + class MENGE_API SimXMLLoader { + public: + /*! + * @brief Constructor + * + * @param sim The simulator to populate based on definition in XML. + */ + SimXMLLoader( XMLSimulatorBase * sim ); + + /*! + * @brief Parse the xml and load the given simulator. + * + * @param xmlName The path to the xml file simulation specification. + * @param agentInit The AgentInitializer necessary to parse AgentSet properties + * @param verbose Determines if parsing outputs progress information (true) + * or parses silently (false). + * @returns True if the simulation is successfully loaded, false otherwise. + */ + bool loadFromXML( const std::string & xmlName, AgentInitializer * agentInit, bool verbose=false ); + + protected: + /*! + * @brief The folder in which the scene configuration file appears + */ + std::string _sceneFldr; + + /*! + * @brief The simulator to populate based on the contents of + * the xml. + */ + XMLSimulatorBase * _sim; + + /*! + * @brief Parses the definition of an AgentGroup. + * + * @param node A pointer to the XML node containing the definition. + * @param agentInit The AgentInitializer necessary to parse AgentProfile properties + * @returns A boolean reporting success (true) or failure (false). + */ + bool parseAgentGroup( TiXmlElement * node, AgentInitializer * agentInit ); + + + /*! + * @brief Parses the definition of an obstacleset. + * + * @param node A pointer to the XML node containing the obstacleset. + * @returns A boolean reporting success (true) or failure (false). + */ + bool parseObstacleSet( TiXmlElement * node ); + + /*! + * @brief Parses the definition of an agent profile. + * + * @param node A pointer to the XML node containing the definition. + * @param agentInit The AgentInitializer necessary to parse AgentProfile properties + * @returns A boolean reporting success (true) or failure (false). + */ + bool parseAgentProfile( TiXmlElement * node, AgentInitializer * agentInit ); + + /*! + * @brief The number of agents loaded. + */ + unsigned int _agtCount; + + /*! + * @brief Mapping from agent profile name to agent initializer. + */ + HASH_MAP< std::string, AgentInitializer * > _profiles; + }; + } // namespace Agents +} // namespace Menge +#endif // __SIM_XML_LOADER__ diff --git a/src/Menge/MengeCore/Agents/SimulatorBase.h b/src/Menge/MengeCore/Agents/SimulatorBase.h new file mode 100644 index 00000000..3bc3ec46 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimulatorBase.h @@ -0,0 +1,313 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __SIMULATOR_BASE_H__ +#define __SIMULATOR_BASE_H__ + +/*! + * @file SimulatorBase.h + * @brief Contains the SimulatorBase class - the common, generic simulator to + * work with different types of agents. It is templated on the Agent type. + */ + +// UTILS +#include "mengeCommon.h" +#include "Utils.h" +// Ped Models +#include "SimulatorInterface.h" +#include "AgentInitializer.h" +#include "SpatialQueries/SpatialQuery.h" + +// STL +#include + +#if HAVE_OPENMP || _OPENMP +#include +#endif + +namespace Menge { + + namespace Agents { + + /*! + * @brief Defines the basic simulator. It is responsible for tracking agents and + * obstacles as well as initializing such from files. + */ + template < class Agent > + class SimulatorBase : public SimulatorInterface { + public: + /*! + * @brief Constructs a simulator instance. + */ + SimulatorBase(); + + /*! + * @brief Destorys a simulator instance. + */ + ~SimulatorBase(); + + /*! + * @brief Lets the simulator perform a simulation step and updates the + * two-dimensional _p and two-dimensional velocity of + * each agent. + */ + void doStep(); + + /*! + * @brief Initalize spatial query structure. + */ + virtual bool initSpatialQuery(); + + /*! + * @brief After all agents and all obstacles have been added to the scene + * does the work to finish preparing the simulation to be run. + * + * This work is performed when the simulator is done being initialized. + * If a particular new pedestrian simulator requires particular finalization + * work, this function should be sub-classed and the parent class's + * version of the function should be explicitly called before any additional + * work is performed. + */ + virtual void finalize(); + + /*! + * @brief Accessor for agents. + * + * @param agentNo The number of the agent who is to be retrieved. + * This is *not* the same as the agent identifier. + * It is merely the local index of the agent in the + * simulator's local store. + * @returns A pointer to the agent. + */ + virtual BaseAgent * getAgent( size_t agentNo ) { return &_agents[ agentNo ]; } + + /*! + * @brief Const accessor for agents. + * + * @param agentNo The number of the agent who is to be retrieved. + * This is *not* the same as the agent identifier. + * It is merely the local index of the agent in the + * simulator's local store. + * @returns A pointer to the agent. + */ + virtual const BaseAgent * getAgent( size_t agentNo ) const { return &_agents[ agentNo ]; } + + /*! + * @brief Add an agent with specified position to the simulator whose properties + * are defined by the given agent initializer. + * + * It uses the agent initializer to define the values of the remaining agent parameters + * + * @param pos The 2d vector representing the agent's position + * @param agentInit The AgentInitializer necessary to parse AgentSet properties + * @returns A pointer to the agent (if initialization was succesful) or NULL if failed. + */ + virtual BaseAgent * addAgent( const Vector2 & pos, AgentInitializer * agentInit ); + + /*! + * @brief Returns the count of agents in the simulation. + * + * @returns The count of agents in the simulation. + */ + virtual size_t getNumAgents() const { return _agents.size(); } + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return false; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * + * @param tagName The name of the candidate experiment XML tag. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return false; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * + * // TODO: Define the conditions of success/failure. + * + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns True if the parameter was successfully set, false otherwise. + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( XMLParamException ); + + protected: + + /*! + * @brief Computes the neighbors for the given agent. + * + * @param agent The agent whose neighbors are to be computed. + */ + void computeNeighbors( Agent * agent ); + + /*! + * @brief The collection of agents in the simulation + */ + std::vector< Agent > _agents; + }; + + //////////////////////////////////////////////////////////////// + // Implementation of SimulatorBase + //////////////////////////////////////////////////////////////// + + template < class Agent > + SimulatorBase::SimulatorBase(): SimulatorInterface(), _agents() { + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + SimulatorBase::~SimulatorBase() { + _agents.clear(); + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + void SimulatorBase::doStep() { + assert( _spatialQuery != 0x0 && "Can't run without a spatial query instance defined" ); + + _spatialQuery->updateAgents(); + int AGT_COUNT = static_cast< int >( _agents.size() ); + #pragma omp parallel for + for (int i = 0; i < AGT_COUNT; ++i) { + computeNeighbors( &(_agents[i]) ); + _agents[i].computeNewVelocity(); + } + + #pragma omp parallel for + for (int i = 0; i < AGT_COUNT; ++i) { + _agents[i].update( TIME_STEP ); + } + + _globalTime += TIME_STEP; + + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + bool SimulatorBase::initSpatialQuery() { + assert( _spatialQuery != 0x0 && "Can't run without a spatial query instance defined" ); + + const size_t AGT_COUNT = _agents.size(); + std::vector< BaseAgent * > agtPointers( AGT_COUNT ); + for ( size_t a = 0; a < AGT_COUNT; ++a ) { + agtPointers[ a ] = &_agents[a]; + } + _spatialQuery->setAgents( agtPointers ); + + _spatialQuery->processObstacles(); + + return true; + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + void SimulatorBase::finalize() { + SimulatorInterface::finalize(); + + // initialize agents + for ( size_t i = 0; i < _agents.size(); ++i ) { + _agents[ i ].initialize(); + } + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + BaseAgent * SimulatorBase::addAgent( const Vector2 & pos, AgentInitializer * agentInit ) { + Agent agent; + + agent._pos = pos; + agent._id = _agents.size(); + if ( ! agentInit->setProperties( &agent ) ) { + logger << Logger::ERR_MSG << "Error initializing agent " << agent._id << "\n"; + return 0x0; + } + _agents.push_back(agent); + + return &_agents[ _agents.size() - 1 ]; + } + + //////////////////////////////////////////////////////////////// + + template < class Agent > + bool SimulatorBase::setExpParam( const std::string & paramName, const std::string & value ) throw( XMLParamException ) { + + if ( paramName == "time_step" ) { + try { + LOGICAL_TIME_STEP = toFloat( value ); + } catch ( UtilException ) { + throw XMLParamException( std::string( "Common parameters \"time_step\" value couldn't be converted to a float. Found the value: " ) + value ); + } + } else { + return false; + } + + return true; + } + + //////////////////////////////////////////////////////////////// + + template< class Agent > + void SimulatorBase::computeNeighbors( Agent * agent ) { + // obstacles + agent->startQuery(); + _spatialQuery->obstacleQuery(agent); + + // agents + if ( agent->_maxNeighbors > 0 ) { + _spatialQuery->agentQuery(agent); + } + } + } // namespace Agents +} // namespace Menge +#endif // __SIMULATOR_BASE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SimulatorInterface.cpp b/src/Menge/MengeCore/Agents/SimulatorInterface.cpp new file mode 100644 index 00000000..6304eb6d --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimulatorInterface.cpp @@ -0,0 +1,116 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimulatorInterface.h" +#include "Obstacle.h" +#include "SpatialQueries/SpatialQuery.h" +#include "Elevations/ElevationFlat.h" +#include "Core.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of SimulatorInterface + //////////////////////////////////////////////////////////////// + + float SimulatorInterface::LOGICAL_TIME_STEP = 0.1f; + + float SimulatorInterface::TIME_STEP = 0.1f; + + size_t SimulatorInterface::SUB_STEPS = 0; + + //////////////////////////////////////////////////////////////////////////// + + SimulatorInterface::SimulatorInterface():XMLSimulatorBase(), _globalTime(0.f), _elevation(0x0), _spatialQuery(0x0) { + } + + //////////////////////////////////////////////////////////////////////////// + + SimulatorInterface::~SimulatorInterface() { + + if ( _spatialQuery != 0x0 ) _spatialQuery->destroy(); + if ( _elevation ) _elevation->destroy(); + } + + //////////////////////////////////////////////////////////////////////////// + + float SimulatorInterface::getElevation( const BaseAgent * agent ) const { + return _elevation->getElevation( agent ); + } + + //////////////////////////////////////////////////////////////////////////// + + float SimulatorInterface::getElevation( const Vector2 & point ) const { + return _elevation->getElevation( point ); + } + + //////////////////////////////////////////////////////////////////////////// + + void SimulatorInterface::setElevationInstance( Elevation * elevation ) { + assert( _elevation == 0x0 && "Trying to set the elevation that already exists" ); + _elevation = elevation; + } + + //////////////////////////////////////////////////////////////// + + void SimulatorInterface::setSpatialQuery( SpatialQuery * spatialQuery ) { + assert( _spatialQuery == 0x0 && "Trying to set the spatial query when one already exists" ); + _spatialQuery = spatialQuery; + } + + + //////////////////////////////////////////////////////////////// + + bool SimulatorInterface::queryVisibility( const Vector2& point1, const Vector2& point2, float radius ) const { + return _spatialQuery->queryVisibility( point1, point2, radius ); + } + + //////////////////////////////////////////////////////////////// + + void SimulatorInterface::finalize() { + if ( _elevation == 0x0 ) { + logger << Logger::WARN_MSG << "No elevation implementation specified. Using \"flat\" implementation."; + _elevation = new FlatElevation(); + Menge::ELEVATION = _elevation; + } + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SimulatorInterface.h b/src/Menge/MengeCore/Agents/SimulatorInterface.h new file mode 100644 index 00000000..b497d1b1 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimulatorInterface.h @@ -0,0 +1,291 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimulatorInterface.h + * @brief The definition of the interface of the simulator required + * by the finite state machine. + */ +#ifndef __SIMULATOR_INTERFACE_H__ +#define __SIMULATOR_INTERFACE_H__ + +#include "CoreConfig.h" +#include "XMLSimulatorBase.h" +#include "Math/Vector2.h" +using namespace Menge::Math; +#include +#include "Core.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class BaseAgent; + class SpatialQuery; + class Obstacle; + class Elevation; + + /*! + * @brief The basic simulator interface required by the fsm. + */ + class MENGE_API SimulatorInterface: public XMLSimulatorBase { + public: + /*! + * @brief Default constructor. + */ + SimulatorInterface(); + + /*! + * @brief Destructor + */ + virtual ~SimulatorInterface(); + + /*! + * @brief Returns the count of agents in the simulation. + * + * @returns The count of agents in the simulation. + */ + virtual size_t getNumAgents() const = 0; + + /*! + * @brief Accessor for agents. + * + * @param agentNo The number of the agent who is to be retrieved. + * This is *not* the same as the agent identifier. + * It is merely the local index of the agent in the + * simulator's local store. + * @returns A pointer to the agent. + */ + virtual BaseAgent * getAgent( size_t agentNo ) = 0; + + /*! + * @brief Const accessor for agents. + * + * @param agentNo The number of the agent who is to be retrieved. + * This is *not* the same as the agent identifier. + * It is merely the local index of the agent in the + * simulator's local store. + * @returns A pointer to the agent. + */ + virtual const BaseAgent * getAgent( size_t agentNo ) const = 0; + + /*! + * @brief Lets the simulator perform a simulation step and updates the + * two-dimensional _p and two-dimensional velocity of + * each agent. + */ + virtual void doStep() = 0; + + /*! + * @brief After all agents and all obstacles have been added to the scene + * does the work to finish preparing the simulation to be run. + * + * This work is performed when the simulator is done being initialized. + * If a particular new pedestrian simulator requires particular finalization + * work, this function should be sub-classed and the parent class's + * version of the function should be explicitly called before any additional + * work is performed. + */ + virtual void finalize(); + + /*! + * @brief Returns the global time of the simulation. + * + * @returns The present global time of the simulation (zero initially). + */ + inline float getGlobalTime() const { return _globalTime; } + + /*! + * @brief Sets the time step of the simulation. + * + * @param timeStep The time step of the simulation. + * Must be positive. + */ + inline void setTimeStep(float timeStep) { LOGICAL_TIME_STEP = timeStep; updateEffTimeStep(); } + + /*! + * @brief Sets the number of intermediate computation sub steps to take. + * + * For the given sim time step, this number of sub steps will be taken. + * This decreases the effective time step, but the simulation state to the outside + * world is only reported at the simulation's *official* time step rate. + * + * @param subSteps The number of sub steps to take. + */ + inline void setSubSteps(size_t subSteps) { SUB_STEPS = subSteps; updateEffTimeStep(); } + + /*! + * @brief Returns the logical time step of the simulation. + * + * @returns The present time step of the simulation. + */ + inline float getTimeStep() const { return LOGICAL_TIME_STEP; } + + /*! + * @brief Returns the elevation of the given agent. + * + * @param agent The agent. + * @returns The elevation for the given agent. + */ + float getElevation( const BaseAgent * agent ) const; + + /*! + * @brief Returns the elevation of the x-z position. + * + * @param point The x-z point. + * @returns The elevation at the given point. + */ + float getElevation( const Vector2 & point ) const; + + /*! + * @brief Set the elevation instance of the simulator + * + * @param elevation The elevation object. + */ + void setElevationInstance( Elevation * elevation ); + + /*! + * @brief Set the elevation instance of the simulator + * + * @returns The elevation instance. + */ + Elevation * getElevationInstance() { return _elevation; } + + /*! + * @brief Reports if the elevation has been set. + * + * @returns True if the elevation has been set, false otherwise. + */ + bool hasElevation() const { return _elevation != 0x0; } + + /*! + * @brief Sets the spatial query instance of the simulator. + * + * @param spatialQuery The spatial query object. + */ + void setSpatialQuery( SpatialQuery * spatialQuery ); + + /*! + * @brief get the spatial query instance of the simulator. + * + * @returns a pointer to The spatial query object. + */ + SpatialQuery * getSpatialQuery() { return _spatialQuery;}; + + /*! + * @brief Reports if the spatial query has been set. + * + * @returns True if the elevation has been set, false otherwise. + */ + bool hasSpatialQuery() const { return _spatialQuery != 0x0; } + + + /*! + * @brief Performs a visibility query between the two specified + * points with respect to the obstacles. + * + * The obstacles are one-sided. So, the ordering of point1 and point2 matter. + * Looking from the inside out is not equivalent to looking from the outside in. + * + * @param point1 The first point of the query. + * @param point2 The second point of the query. + * @param radius The minimal distance between the line + * connecting the two points and the obstacles + * in order for the points to be mutually + * visible (optional). Must be non-negative. + * @returns A boolean specifying whether the two points are mutually + * visible. Returns true when the obstacles have not been + * processed. + */ + bool queryVisibility(const Vector2& point1, const Vector2& point2, float radius = 0.0f) const; + + /*! + * @brief Reports the number of simulation substeps to take. + * + * @returns The number of substeps to take. + */ + inline size_t getSubSteps() const { return SUB_STEPS; } + + protected: + + /*! + * @brief Updates the effective time step -- how large an actual simulation time + * step is due to computation sub-steps. + * + */ + void updateEffTimeStep() { SIM_TIME_STEP = TIME_STEP = LOGICAL_TIME_STEP / ( 1.f + SUB_STEPS ); } + + /*! + * @brief The logical simulation time step. The simulation's state is communicated + * to the outside world at this time step. In practice, sub-steps can decrease + * the effective time step. + */ + static float LOGICAL_TIME_STEP; + + /*! + * @brief The effective simulation time step - takes into account time step and + * computation sub-steps. + */ + static float TIME_STEP; + + /*! + * @brief The number of intermediate steps taken between subsequent simulation + * time steps. + */ + static size_t SUB_STEPS; + + /*! + * @brief The total accumulated simulation time. + */ + float _globalTime; + + /*! + * @brief Data structure for reporting the elevation data of agents. + * This allows the simulation to be more than 2D (and more than + * topologically planar.) + */ + Elevation * _elevation; + + /*! + * @brief The data structure used to perform spatial queries. + */ + SpatialQuery * _spatialQuery; + }; + } // namespace Agents +} // namespace Menge +#endif // __SIMULATOR_INTERFACE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SimulatorState.cpp b/src/Menge/MengeCore/Agents/SimulatorState.cpp new file mode 100644 index 00000000..727c6dca --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimulatorState.cpp @@ -0,0 +1,68 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimulatorState.h" +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////// + // Implementation of SimulatorState + //////////////////////////////////////////////////////////////////// + + SimulatorState::SimulatorState(): _agentStates() { + } + + //////////////////////////////////////////////////////////////////// + + void SimulatorState::setAgentState( size_t id, const std::string & stateName ) { + _agentStates[ id ] = stateName; + } + + //////////////////////////////////////////////////////////////////// + + const std::string SimulatorState::getAgentState( size_t id ) const { + assert( _agentStates.count( id ) == 1 && "Trying to retrieve a state name for an unregistered agent id" ); + return _agentStates.find( id )->second; + } + + } // namespace Agents + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SimulatorState.h b/src/Menge/MengeCore/Agents/SimulatorState.h new file mode 100644 index 00000000..cb68e7ef --- /dev/null +++ b/src/Menge/MengeCore/Agents/SimulatorState.h @@ -0,0 +1,96 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimulatorState.h + * @brief A snapshot of the simulator state. + * + * TODO: Make this a complete snapshot. + */ + +#ifndef __SIMULATOR_STATE_H__ +#define __SIMULATOR_STATE_H__ + +#include "mengeCommon.h" +#include + +namespace Menge { + + namespace Agents { + /*! + * @brief A class which caches the state of the simulator. + * + * This version of the class is, as yet, incomplete. Ultimately, it + * will store all critical parameters of the simulator such that the + * simulation can be restarted from this state. + * + * This version is currently used to determine agent's starting state. + */ + class SimulatorState { + public: + /*! + * @brief Constructor. + */ + SimulatorState(); + + /*! + * @brief Sets the state for the given agent. + * + * @param id The identifier of the agent. + * @param stateName The name of the state to which the agent belongs. + */ + void setAgentState( size_t id, const std::string & stateName ); + + /*! + * @brief Reports the state name for the given agent. + * + * @param id The identifier of the agent. + * @returns The name of this agent's start state. + */ + const std::string getAgentState( size_t id ) const; + + protected: + /*! + * @brief A mapping from agent id to state name + */ + HASH_MAP< size_t, std::string > _agentStates; + }; + + } // namespace Agents +} // namespace Menge +#endif // __SIMULATOR_STATE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.cpp new file mode 100644 index 00000000..59afc096 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.cpp @@ -0,0 +1,189 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AgentKDTree.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of AgentKDTree + ///////////////////////////////////////////////////////////////////////////// + + AgentKDTree::AgentKDTree(): _agents(), _tree() { + } + + ///////////////////////////////////////////////////////////////////////////// + + void AgentKDTree::setAgents( const std::vector< BaseAgent * > & agents ) { + const size_t AGT_COUNT = agents.size(); + _agents.resize( AGT_COUNT ); + for ( size_t i = 0; i < AGT_COUNT; ++i ) { + _agents[ i ] = agents[i]; + } + _tree.resize( 2 * AGT_COUNT - 1 ); + + if ( AGT_COUNT > 0 ) { + buildTreeRecursive( 0, AGT_COUNT, 0 ); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void AgentKDTree::buildTree() { + if ( _agents.size() > 0 ) { + buildTreeRecursive( 0, _agents.size(), 0 ); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void AgentKDTree::agentQuery( ProximityQuery *filter) const { + float range = filter->getMaxAgentRange(); + queryTreeRecursive( filter, filter->getQueryPoint(), range, 0 ); + } + + ///////////////////////////////////////////////////////////////////////////// + + void AgentKDTree::buildTreeRecursive(size_t begin, size_t end, size_t node) { + _tree[node]._begin = begin; + _tree[node]._end = end; + const Vector2 & pos = _agents[begin]->_pos; + _tree[node]._minX = _tree[node]._maxX = pos.x(); + _tree[node]._minY = _tree[node]._maxY = pos.y(); + + for (size_t i = begin + 1; i < end; ++i) { + const Vector2 & posI = _agents[i]->_pos; + _tree[node]._maxX = std::max(_tree[node]._maxX, posI.x()); + _tree[node]._minX = std::min(_tree[node]._minX, posI.x()); + _tree[node]._maxY = std::max(_tree[node]._maxY, posI.y()); + _tree[node]._minY = std::min(_tree[node]._minY, posI.y()); + } + + if (end - begin > MAX_LEAF_SIZE) { + /* No leaf node. */ + const bool isVertical = (_tree[node]._maxX - _tree[node]._minX > _tree[node]._maxY - _tree[node]._minY); + const float splitValue = (isVertical ? 0.5f * (_tree[node]._maxX + _tree[node]._minX) : 0.5f * (_tree[node]._maxY + _tree[node]._minY)); + + size_t left = begin; + size_t right = end; + + + while (left < right) { + Vector2 posL = _agents[left]->_pos; + while (left < right && (isVertical ? posL.x() : posL.y()) < splitValue) { + ++left; + posL = _agents[left]->_pos; + } + + Vector2 posR = _agents[right-1]->_pos; + while (right > left && (isVertical ? posR.x() : posR.y()) >= splitValue) { + --right; + posR = _agents[right-1]->_pos; + } + + if (left < right) { + std::swap(_agents[left], _agents[right-1]); + ++left; + --right; + } + } + + size_t leftSize = left - begin; + + if (leftSize == 0) { + ++leftSize; + ++left; + ++right; + } + + _tree[node]._left = node + 1; + _tree[node]._right = node + 1 + (2 * leftSize - 1); + + buildTreeRecursive(begin, left, _tree[node]._left); + buildTreeRecursive(left, end, _tree[node]._right); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void AgentKDTree::queryTreeRecursive( ProximityQuery *filter, Vector2 pt, float& rangeSq, size_t node) const { + if (_tree[node]._end - _tree[node]._begin <= MAX_LEAF_SIZE) { + for (size_t i = _tree[node]._begin; i < _tree[node]._end; ++i) { + float distance = pt.distanceSq(_agents[i]->_pos); + if (distance < rangeSq){ + filter->filterAgent( _agents[i], distance ); + } + rangeSq = filter->getMaxAgentRange(); + } + } else { + float x = pt.x(); + float y = pt.y(); + const float distSqLeft = sqr(std::max(0.0f, _tree[_tree[node]._left ]._minX - x)) + + sqr(std::max(0.0f, x - _tree[_tree[node]._left ]._maxX)) + + sqr(std::max(0.0f, _tree[_tree[node]._left ]._minY - y)) + + sqr(std::max(0.0f, y - _tree[_tree[node]._left ]._maxY)); + + const float distSqRight = sqr(std::max(0.0f, _tree[_tree[node]._right]._minX - x)) + + sqr(std::max(0.0f, x - _tree[_tree[node]._right]._maxX)) + + sqr(std::max(0.0f, _tree[_tree[node]._right]._minY - y)) + + sqr(std::max(0.0f, y - _tree[_tree[node]._right]._maxY)); + + if (distSqLeft < distSqRight) { + if (distSqLeft < rangeSq) { + queryTreeRecursive(filter, pt, rangeSq, _tree[node]._left); + + if (distSqRight < rangeSq) { + queryTreeRecursive(filter, pt, rangeSq, _tree[node]._right); + } + } + } else if (distSqRight < rangeSq) { + queryTreeRecursive(filter, pt, rangeSq, _tree[node]._right); + + if (distSqLeft < rangeSq) { + queryTreeRecursive(filter, pt, rangeSq, _tree[node]._left); + } + } + } + } + + ///////////////////////////////////////////////////////////////////////////// + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.h b/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.h new file mode 100644 index 00000000..bfca4b3c --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/AgentKDTree.h @@ -0,0 +1,182 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __AGENT_KD_TREE_H__ +#define __AGENT_KD_TREE_H__ + +/*! + * @file AgentKDTree.h + * @brief Contains the definition of the AgentKDTree class. + * Performs spatial queries for agents + */ + +// STL +#include "CoreConfig.h" +#include +#include +#include "SpatialQueries/ProximityQuery.h" + + +namespace Menge { + + /*! + * @namespace Agents + * @brief The namespace that contains the basic simulation mechanisms. + */ + namespace Agents { + + // FORWARD DECLARATIONS + class BaseAgent; + + // TODO: Adapt this so that the number of agents can be changed -- i.e. removing and + // introducing new agents in the simulation + + /*! + * @brief A kd-tree for performing nearest-neighbor searches. + * + * The agents are partitioned according to a greedy partitioning algorithm. + */ + class MENGE_API AgentKDTree { + private: + /*! + * @brief A node in the kd-tree -- a group of one or more agents and their extents. + */ + struct AgentTreeNode { + /*! + * @brief The beginning node number. + */ + size_t _begin; + + /*! + * @brief The ending node number. + */ + size_t _end; + + /*! + * @brief The left node number. + */ + size_t _left; + + /*! + * @brief The maximum x-coordinate. + */ + float _maxX; + + /*! + * @brief The maximum y-coordinate. + */ + float _maxY; + + /*! + * @brief The minimum x-coordinate. + */ + float _minX; + + /*! + * @brief The minimum y-coordinate. + */ + float _minY; + + /*! + * @brief The right node number. + */ + size_t _right; + }; + public: + /*! + * @brief Constructs an Agent kd-tree instance. + */ + explicit AgentKDTree(); + + /*! + * @brief Define the set of agents on which kd-tree will query. + */ + void setAgents( const std::vector< BaseAgent * > & agents ); + + /*! + * @brief Builds a kd-tree on the set of agents. + */ + void buildTree(); + + /*! + * @brief gets agents within a range, and passes them to the supplied filter + * @param filter a pointer for the filter object + */ + void agentQuery( ProximityQuery *filter) const; + + protected: + /*! + * @brief Does the full work of constructing the kd-tree. + * + * @param begin The index of the first agent in the region of the tree. + * @param end The index of the last (just outside). So, the + * agents in this branch are in the interval [begin, end) + * @param node The index of the node to build. + */ + void buildTreeRecursive(size_t begin, size_t end, size_t node); + + /*! + * @brief Computes the agent neighbors of the specified agent by doing a + * recursive search. + * + * @param filter spatial query filter to use + * @param pt the start point for the query + * @param rangeSq The squared range around the agent. + * @param node The current node to search in. + */ + void queryTreeRecursive( ProximityQuery *filter, Vector2 pt, float& rangeSq, size_t node) const; + + /*! + * @brief The agents being partitioned by the kd-tree. + */ + std::vector< const BaseAgent * > _agents; + + /*! + * @brief The tree structure. + */ + std::vector _tree; + + /*! + * @brief The maximum number of agents allowed in a tree leaf node. + */ + static const size_t MAX_LEAF_SIZE = 10; + }; + } // namespace Agents +} // namespace Menge + +#endif // __AGENT_KD_TREE_H__ diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.cpp new file mode 100644 index 00000000..b8efa1d8 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.cpp @@ -0,0 +1,124 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +// UTILS +#include "KNearestQuery.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION OF KNearestQuery CLASS + //////////////////////////////////////////////////////////////////////// + + + void KNearestQuery::filterAgent(const BaseAgent * agent, float distanceSquared){ + + //if the agent is too far, and we have enough agents, just exit + if (distanceSquared >= _maxAgentResultDistance && _agentResults.size() == _maxAgentResults) + return; + + //if not, add the agent + if (_agentResults.size() < _maxAgentResults) { + + _agentResults.push_back(NearAgent(distanceSquared,agent)); + } + + //we are trusting that results are in order + size_t i = _agentResults.size() - 1; + while (i != 0 && distanceSquared < _agentResults[i-1].distanceSquared) { + _agentResults[i] = _agentResults[i-1]; + --i; + } + + _agentResults[i] = NearAgent(distanceSquared,agent); + + if (distanceSquared > _maxAgentResultDistance) + _maxAgentResultDistance = distanceSquared; + + }; + + + /////////////////////////////////////////////////////////// + + void KNearestQuery::filterObstacle(const Obstacle * obstacle, float distanceSquared) { + + //make sure that the obstacle is not already disqualified + if (distanceSquared >= _maxObstacleResultDistance && _obstacleResults.size() == _maxObstacleResults) + return; + + if (_obstacleResults.size() != _maxObstacleResults){ + _obstacleResults.push_back(NearObstacle(distanceSquared, obstacle) ); + } + + size_t i = _obstacleResults.size() - 1; + while ( i != 0 && distanceSquared < _obstacleResults[i-1].distanceSquared) { + _obstacleResults[i] = _obstacleResults[i-1]; + --i; + } + + _obstacleResults[i] = NearObstacle(distanceSquared, obstacle); + + if (distanceSquared > _maxObstacleResultDistance) + _maxObstacleResultDistance = distanceSquared; + }; + + /////////////////////////////////////////////////////////// + + void KNearestQuery::startQuery() { + _agentResults.clear(); + _obstacleResults.clear(); + _maxAgentResultDistance = 9999; + _maxObstacleResultDistance = 9999; + _queryPoint = Vector2(0,0); + } + + /////////////////////////////////////////////////////////// + + float KNearestQuery::getMaxAgentRange() { + if (_agentResults.size() == _maxAgentResults) + return _maxAgentResultDistance; + + return _initialRange; + } + + } // namespace Agents +} // namespace Menge + + diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.h b/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.h new file mode 100644 index 00000000..ad156e9a --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/KNearestQuery.h @@ -0,0 +1,236 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file KNearestQuery.h + * @brief Spatial Query which stores the k-nearest agents and obstacles + */ +#ifndef __K_NEAREST_QUERY_H__ +#define __K_NEAREST_QUERY_H__ + +// UTILS +#include "ProximityQuery.h" +#include "SpatialQueryStructs.h" +#include + +namespace Menge { + + namespace Agents { + + /*! + * @brief The K-Nearest query class + * + * A spatial query which returns the k nearest agents and obstacles in the spatial query + * The query doesn't know where the point it, it is given distances + * in this case, K is set to the maxAgentResults and maxObstacleResults + * + */ + class KNearestQuery : public ProximityQuery { + public: + /*! + * @brief default Constructor. + */ + KNearestQuery() : ProximityQuery(), _maxAgentResultDistance(0.0f), _maxObstacleResultDistance(0.0f), _queryPoint(0,0), _initialRange(100){}; + + + /*! + * @brief filters an agent and determines if it is within the set of k-nearest neighbors + * + * @param agent the agent to consider + * @param distSq the distance to the agent + */ + void filterAgent(const BaseAgent * agent, float distSq); + + /*! + * @brief filters an obstacle and determines if it is within the set of k-nearest neighbors + * + * @param obstacle the obstacle to consider + * @param distSq the distance to the obstacle + */ + void filterObstacle(const Obstacle * obstacle, float distSq); + + /*! + * @brief sets the max number of agent results for this query to store + * + * @param results the number of agent results to store + */ + void setMaxAgentResults(size_t results){_maxAgentResults = results;} + + /*! + * @brief sets the max number of obstacle results for this query to store + * + * @param results the number of obstacle results to store + */ + void setMaxObstacleResults(size_t results){_maxObstacleResults = results;} + + + /*! + * @brief sets the query point + * + * @param point the query point to be stored + */ + void setQueryPoint(Vector2 point){_queryPoint = point;} + + /*! + * @brief sets the query point + * + * @param range the squared range to search for nearby candidates + */ + void setQueryRangeSq(float range){_initialRange = range;} + + + /*! + * @brief gets the max number of agent results for this query to store + * + * @returns the number of agent results to store + */ + size_t maxAgentResults(){ return _maxAgentResults;} + + /*! + * @brief gets the max number of obstacle results for this query to store + * + * @returns the number of obstacle results to store + */ + size_t maxObstacleResults(){ return _maxObstacleResults;} + + /*! + * @brief gets the number of agent results stored currently + * + * @returns the number of agent results in the query + */ + size_t agentResultCount(){ return _agentResults.size();} + + /*! + * @brief gets the number of obstacle results stored currently + * + * @returns the number of obstacle results in the query + */ + size_t obstacleResultCount(){ return _obstacleResults.size();} + + + /*! + * @brief clears the result vectors. Resets the query + */ + void startQuery(); + + /*! + * @brief gets the start point for the query + * + * @returns the query point for this query + */ + virtual Vector2 getQueryPoint() { return _queryPoint;}; + + /*! + * @brief gets the ith agent result + * + * @param i the index of the agent to get + * @returns the result pair in question + */ + NearAgent getAgentResult(size_t i) { return _agentResults[i];}; + + /*! + * @brief gets the ith obstacle result + * + * @param i the index of the obstacle to get + * @returns the result pair in question + */ + NearObstacle getObstacleResult(size_t i) { return _obstacleResults[i];}; + + /*! + * @brief updates the max agent query range if conditions inside the query are met + * typically, we don't shrink the query range until the result set is full + * + * @returns the new query distance. Typically this is the initial value.d + */ + virtual float getMaxAgentRange(); + + /*! + * @brief updates the max query obstacle range if conditions inside the query are met + * typically, we don't shrink the query range until the result set is full + * + * @returns the new query distance. Typically this is the initial value. + */ + virtual float getMaxObstacleRange() { return _initialRange; }; + + protected: + /*! + * @brief the max number of agent results to store + */ + size_t _maxAgentResults; + + /*! + * @brief the max number of obstacle results to store + */ + size_t _maxObstacleResults; + + /*! + * @brief the max distance to an agent result. Useful for informing the spatial query + * to stop searching further + */ + float _maxAgentResultDistance; + + /*! + * @brief the max distance to an obstacle result. Useful for informing the spatial query + * to stop searching further + */ + float _maxObstacleResultDistance; + + + /*! + * @brief vector of pairs. Each pair contains a distance to an agent, and the agent + */ + std::vector _agentResults; + + /*! + * @brief vector of pairs. Each pair contains a distance to an obstacle, and the obstacle + */ + std::vector _obstacleResults; + + /*! + * @brief the start point for the query + */ + Vector2 _queryPoint; + + /*! + * @brief the base max range of queries + */ + float _initialRange; + }; + } // namespace Agents +} // namespace Menge +#endif diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.cpp new file mode 100644 index 00000000..8e95ecf5 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.cpp @@ -0,0 +1,295 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ObstacleKDTree.h" +#include "BaseAgent.h" +#include "Math/consts.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of ObstacleKDTree + ///////////////////////////////////////////////////////////////////////////// + + ObstacleKDTree::ObstacleKDTree(): _obstacles(), _tree(0x0) { + } + + ///////////////////////////////////////////////////////////////////////////// + + ObstacleKDTree::~ObstacleKDTree() { + deleteTree(); + } + + ///////////////////////////////////////////////////////////////////////////// + + void ObstacleKDTree::buildTree( const std::vector< Obstacle * > obstacles ) { + deleteTree(); + + _obstacles.assign( obstacles.begin(), obstacles.end() ); + if ( _obstacles.size() > 0 ) { + std::vector< Obstacle * > temp; + temp.assign( _obstacles.begin(), _obstacles.end() ); + _tree = buildTreeRecursive( temp ); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void ObstacleKDTree::obstacleQuery( ProximityQuery *filter ) const { + float range = filter->getMaxObstacleRange(); + queryTreeRecursive(filter, filter->getQueryPoint(), range, _tree ); + } + + ///////////////////////////////////////////////////////////////////////////// + + bool ObstacleKDTree::queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const { + return queryVisibilityRecursive(q1, q2, radius, _tree); + } + + ///////////////////////////////////////////////////////////////////////////// + + ObstacleTreeNode* ObstacleKDTree::buildTreeRecursive( const std::vector& obstacles) { + if ( obstacles.empty() ) { + return 0x0; + } else { + ObstacleTreeNode* const node = new ObstacleTreeNode; + + size_t optimalSplit = 0; + size_t minLeft = obstacles.size(); + size_t minRight = obstacles.size(); + + for (size_t i = 0; i < obstacles.size(); ++i) { + size_t leftSize = 0; + size_t rightSize = 0; + + const Obstacle* const obstacleI = obstacles[i]; + const Vector2 I0 = obstacleI->getP0(); + const Vector2 I1 = obstacleI->getP1(); + + /* Compute optimal split node. */ + for (size_t j = 0; j < obstacles.size(); ++j) { + if (i == j) { + continue; + } + + const Obstacle* const obstacleJ = obstacles[j]; + const Vector2 J0 = obstacleJ->getP0(); + const Vector2 J1 = obstacleJ->getP1(); + + const float j1LeftOfI = leftOf( I0, I1, J0 ); + const float j2LeftOfI = leftOf( I0, I1, J1 ); + + if (j1LeftOfI >= -EPS && j2LeftOfI >= -EPS) { + ++leftSize; + } else if (j1LeftOfI <= EPS && j2LeftOfI <= EPS ) { + ++rightSize; + } else { + ++leftSize; + ++rightSize; + } + + if (std::make_pair(std::max(leftSize, rightSize), std::min(leftSize, rightSize)) >= std::make_pair(std::max(minLeft, minRight), std::min(minLeft, minRight))) { + break; + } + } + + if (std::make_pair(std::max(leftSize, rightSize), std::min(leftSize, rightSize)) < std::make_pair(std::max(minLeft, minRight), std::min(minLeft, minRight))) { + minLeft = leftSize; + minRight = rightSize; + optimalSplit = i; + } + } + + /* Build split node. */ + std::vector leftObstacles(minLeft); + std::vector rightObstacles(minRight); + + size_t leftCounter = 0; + size_t rightCounter = 0; + const size_t i = optimalSplit; + + const Obstacle* const obstacleI = obstacles[i]; + const Vector2 I0 = obstacleI->getP0(); + const Vector2 I1 = obstacleI->getP1(); + + for (size_t j = 0; j < obstacles.size(); ++j) { + if (i == j) { + continue; + } + + Obstacle* const obstacleJ = obstacles[j]; + const Vector2 J0 = obstacleJ->getP0(); + const Vector2 J1 = obstacleJ->getP1(); + + const float j1LeftOfI = leftOf( I0, I1, J0 ); + const float j2LeftOfI = leftOf( I0, I1, J1 ); + + if (j1LeftOfI >= -EPS && j2LeftOfI >= -EPS ) { + leftObstacles[leftCounter++] = obstacles[j]; + } else if (j1LeftOfI <= EPS && j2LeftOfI <= EPS ) { + rightObstacles[rightCounter++] = obstacles[j]; + } else { + /* Split obstacle j. */ + const float t = det( I1 - I0, J0 - I0 ) / det( I1 -I0, J0 - J1 ); + + const Vector2 splitpoint = J0 + t * ( J1 - J0 ); + + Obstacle* const newObstacle = new Obstacle(); + newObstacle->_point = splitpoint; + newObstacle->_prevObstacle = obstacleJ; + newObstacle->_nextObstacle = obstacleJ->_nextObstacle; + if ( newObstacle->_nextObstacle ) { + obstacleJ->_nextObstacle = newObstacle; + } + newObstacle->_isConvex = true; + newObstacle->_unitDir = obstacleJ->_unitDir; + newObstacle->_length = abs( J1 - newObstacle->_point ); + + newObstacle->_id = _obstacles.size(); + newObstacle->_class = obstacleJ->_class; + + _obstacles.push_back(newObstacle); + + obstacleJ->_nextObstacle = newObstacle; + obstacleJ->_length = abs( J0 - newObstacle->_point ); + + if (j1LeftOfI > 0.0f) { + leftObstacles[leftCounter++] = obstacleJ; + rightObstacles[rightCounter++] = newObstacle; + } else { + rightObstacles[rightCounter++] = obstacleJ; + leftObstacles[leftCounter++] = newObstacle; + } + } + } + + node->_obstacle = obstacleI; + node->_left = buildTreeRecursive(leftObstacles); + node->_right = buildTreeRecursive(rightObstacles); + return node; + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void ObstacleKDTree::queryTreeRecursive( ProximityQuery *filter, Vector2 pt, float& rangeSq, const ObstacleTreeNode* node) const { + if (node == 0) { + return; + } else { + const Obstacle* const obstacle1 = node->_obstacle; + + const Vector2 P0 = obstacle1->getP0(); + const Vector2 P1 = obstacle1->getP1(); + + const float agentLeftOfLine = leftOf( P0, P1, pt); + + queryTreeRecursive(filter, pt, rangeSq, (agentLeftOfLine >= 0.0f ? node->_left : node->_right)); + + const float distSqLine = sqr(agentLeftOfLine) / absSq(P1 - P0); + + if (distSqLine < rangeSq) { + if ( obstacle1->_doubleSided || agentLeftOfLine < 0.0f) { + /* + * Try obstacle at this node only if agent is on right side of + * obstacle (and can see obstacle). + */ + float distSq = distSqPointLineSegment(node->_obstacle->getP0(), node->_obstacle->getP1(), pt); + + filter->filterObstacle(node->_obstacle, distSq); + + rangeSq = filter->getMaxObstacleRange(); + } + + /* Try other side of line. */ + queryTreeRecursive(filter, pt, rangeSq, (agentLeftOfLine >= 0.0f ? node->_right : node->_left)); + } + } + } + + ///////////////////////////////////////////////////////////////////////////// + + bool ObstacleKDTree::queryVisibilityRecursive(const Vector2& q1, const Vector2& q2, + float radius, + const ObstacleTreeNode* node) const { + if (node == 0) { + return true; + } else { + const Obstacle* const obstacle1 = node->_obstacle; + const Obstacle* const obstacle2 = obstacle1->_nextObstacle; + + const float q1LeftOfI = leftOf(obstacle1->_point, obstacle2->_point, q1); + const float q2LeftOfI = leftOf(obstacle1->_point, obstacle2->_point, q2); + const float invLengthI = 1.0f / absSq(obstacle2->_point - obstacle1->_point); + + if (q1LeftOfI >= 0.0f && q2LeftOfI >= 0.0f) { + return queryVisibilityRecursive(q1, q2, radius, node->_left) && ((sqr(q1LeftOfI) * invLengthI >= sqr(radius) && sqr(q2LeftOfI) * invLengthI >= sqr(radius)) || queryVisibilityRecursive(q1, q2, radius, node->_right)); + } else if (q1LeftOfI <= 0.0f && q2LeftOfI <= 0.0f) { + return queryVisibilityRecursive(q1, q2, radius, node->_right) && ((sqr(q1LeftOfI) * invLengthI >= sqr(radius) && sqr(q2LeftOfI) * invLengthI >= sqr(radius)) || queryVisibilityRecursive(q1, q2, radius, node->_left)); + } else if (q1LeftOfI >= 0.0f && q2LeftOfI <= 0.0f) { + /* One can see through obstacle from left to right. */ + return queryVisibilityRecursive(q1, q2, radius, node->_left) && queryVisibilityRecursive(q1, q2, radius, node->_right); + } else { + const float point1LeftOfQ = leftOf(q1, q2, obstacle1->_point); + const float point2LeftOfQ = leftOf(q1, q2, obstacle2->_point); + const float invLengthQ = 1.0f / absSq(q2 - q1); + + return (point1LeftOfQ * point2LeftOfQ >= 0.0f && sqr(point1LeftOfQ) * invLengthQ > sqr(radius) && sqr(point2LeftOfQ) * invLengthQ > sqr(radius) && queryVisibilityRecursive(q1, q2, radius, node->_left) && queryVisibilityRecursive(q1, q2, radius, node->_right)); + } + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void ObstacleKDTree::deleteTree() { + deleteSubTree( _tree ); + _tree = 0x0; + } + + ///////////////////////////////////////////////////////////////////////////// + + void ObstacleKDTree::deleteSubTree( ObstacleTreeNode * node ) { + if ( node != 0x0 ) { + deleteSubTree( node->_left ); + deleteSubTree( node->_right ); + delete node; + } + } + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.h b/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.h new file mode 100644 index 00000000..3b6214c7 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/ObstacleKDTree.h @@ -0,0 +1,202 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __OBSTACLE_KD_TREE_H__ +#define __OBSTACLE_KD_TREE_H__ + +/*! + * @file ObstacleKDTree.h + * @brief Contains the definition of the ObstacleKDTree class. + * Performs spatial queries for Obstacles + */ + +// STL +#include + +// PedModels +#include "CoreConfig.h" +#include "Obstacle.h" +#include "SpatialQueries/ProximityQuery.h" + +namespace Menge { + + namespace Agents { + + // FORWARD DECLARATIONS + class BaseAgent; + + // Forward declarations + + // TODO: This chops up obstacles for the kd-tree. I need to be able to reconstruct them + // i.e. if a piece is close to the agent, I'd like to be able to provide the full + // original line obstacle. + + /*! + * @brief Defines an obstacle kd-tree node. + */ + struct ObstacleTreeNode { + /*! + * @brief The left obstacle tree node. + */ + ObstacleTreeNode* _left; + + /*! + * @brief The obstacle number. + */ + const Obstacle* _obstacle; + + /*! + * @brief The right obstacle tree node. + */ + ObstacleTreeNode* _right; + }; + + /*! + * @brief Defines an obstacle kd-tree. + * + * This structure will create a static kd-tree node on the provided + * set of obstacles. It will modify the obstacles in that some obstacles + * may be cut. + */ + class MENGE_API ObstacleKDTree { + public: + /*! + * @brief Constructs an Obstacle kd-tree instance. + */ + explicit ObstacleKDTree(); + + /*! + * @brief Destroys this kd-tree instance. + */ + ~ObstacleKDTree(); + + /*! + * @brief Builds an obstacle kd-tree on the given set of obstacles. + */ + void buildTree( const std::vector< Obstacle * > obstacles ); + + /*! + * @brief Computes the obstacles within range square of a point + * @param query a pointer for the query to be performed + + */ + void obstacleQuery( ProximityQuery *query) const; + + /*! + * @brief Queries the visibility between two points within a + * specified radius. + * + * @param q1 The first point between which visibility is + * to be tested. + * @param q2 The second point between which visibility is + * to be tested. + * @param radius The radius within which visibility is to be + * tested. + * @returns True if q1 and q2 are mutually visible within the radius; + * false otherwise. + */ + bool queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const; + + protected: + /*! + * @brief Does the full work of constructing the kd-tree. + * + * @param obstacles The set of obstacles to construct this tree around + * @returns The root of the ObstacleKDTree for this set of obstacles + */ + ObstacleTreeNode* buildTreeRecursive( const std::vector& obstacles ); + + /*! + * @brief Computes the obstacle neighbors of the specified point by doing a + * recursive search. + * + * @param query a pointer to the query being performed. + * @param pt the starting point from the query + * @param rangeSq The squared range around the agent. + * @param node The current node in the obstacle tree + + */ + void queryTreeRecursive( ProximityQuery *query, Vector2 pt, float& rangeSq, const ObstacleTreeNode* node) const; + + /*! + * @brief Perform the work, recursively, to determine if q1 can see q2, w.r.t. the obstacles. + * + * @param q1 The originating position. + * @param q2 The target position. + * @param radius The radius within which visibility is to be tested. + * @param node The root of the tree to recursively search. + * @returns True if q1 and q2 are mutually visible within the radius, false otherwise. + */ + bool queryVisibilityRecursive(const Vector2& q1, const Vector2& q2, + float radius, + const ObstacleTreeNode* node) const; + + /*! + * @brief Recursively deletes the obstacle tree. + */ + void deleteTree(); + + /*! + * @brief Recursively deletes an obstacle sub-tree. + * @param node The root of the tree to delete. + */ + void deleteSubTree( ObstacleTreeNode * node ); + + /*! + * @brief The set of obstacles managed by this query structure. + * + * This is *not* necessarily the same as the obstacles assigned. + * The set of obstacles can change as some obstacles may be sub-divided + * during the spatial decomposition. This needs to be corrected. + */ + std::vector _obstacles; + + /*! + * @brief The query tree root. + */ + ObstacleTreeNode* _tree; + + /*! + * @brief The maximum number of obstacles allowed in a tree leaf node. + */ + static const size_t MAX_LEAF_SIZE = 10; + }; + } // namespace Agents +} // namespace Menge + +#endif // __OBSTACLE_KD_TREE_H__ diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/ProximityQuery.h b/src/Menge/MengeCore/Agents/SpatialQueries/ProximityQuery.h new file mode 100644 index 00000000..b28f4270 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/ProximityQuery.h @@ -0,0 +1,137 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ProximityQuery.h + * @brief The base class for all objects which actually perform filtering and store results from spatial queries + */ +#ifndef __SPATIAL_QUERY_FILTER_H__ +#define __SPATIAL_QUERY_FILTER_H__ + + +// UTILS +#include "CoreConfig.h" +#include "Obstacle.h" +#include +#include + +namespace Menge { + + namespace Agents { + + /* + * Forward Declaration + */ + class BaseAgent; + + /*! + * @brief The base class for filtering spatial queries according to proximity + * + * A spatial query performs basic operations on a query structure + * The ProximityQuery class is tasked with taking whatever data the spatialquery gives us + * and filtering the result set to fit our desires. For example + * K-nearest, K-nearest with minRange + * ProximityQueries work with obstacles and agents. They must support BOTH + * Children must overwrite filterAgent and filterObstacle + */ + class MENGE_API ProximityQuery { + public: + /*! + * @brief default Constructor. + */ + ProximityQuery(){}; + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~ProximityQuery() {} + + public: + + + /*! + * @brief resets the query + */ + virtual void startQuery() = 0; + + /*! + * @brief gets the start point for the query + * + * @returns the query point for this Query + */ + virtual Vector2 getQueryPoint() = 0; + + + /*! + * @brief updates the max agent query range if conditions inside the Query are met + * typically, we don't shrink the query range until the result set is full + * + * @returns the current max query range + */ + virtual float getMaxAgentRange() = 0; + + /*! + * @brief updates the max query obstacle range if conditions inside the Query are met + * typically, we don't shrink the query range until the result set is full + * + * @returns the current max query range + */ + virtual float getMaxObstacleRange() = 0; + + /*! + * @brief filters an agent and determines if it needs to be in the result set + * + * CHILDREN MUST OVERWRITE THIS + * @param agent the agent to consider + * @param distSq the distance to the agent + */ + virtual void filterAgent(const BaseAgent * agent, float distSq) = 0; + + /*! + * @brief filters an obstacle and determines if it needs to be in the result set + * + * CHILDREN MUST OVERWRITE THIS + * @param obstacle the obstacle to consider + * @param distSq the distance to the obstacle + */ + virtual void filterObstacle(const Obstacle * obstacle, float distSq) = 0; + + }; + } // namespace Agents +} // namespace Menge +#endif diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.cpp new file mode 100644 index 00000000..80fdb757 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.cpp @@ -0,0 +1,61 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SpatialQueries/SpatialQuery.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SpatialQuery + ///////////////////////////////////////////////////////////////////// + + SpatialQuery::SpatialQuery(): Element(), _testVisibility(false) { + } + + + ///////////////////////////////////////////////////////////////////// + + void SpatialQuery::addObstacle(Obstacle *obs){ + obs->_id = _obstacles.size(); + _obstacles.push_back(obs); + } + + } // namespace Agents +} // namespace Menge diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.h new file mode 100644 index 00000000..8d70b818 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQuery.h @@ -0,0 +1,226 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQuery.h + * @brief The base class for all objects which support agent spatial + * queries including: k-nearest agent neighbor, k-nearest + * obstacles and visibility queries. + */ +#ifndef __SPATIAL_QUERY_H__ +#define __SPATIAL_QUERY_H__ + + +// UTILS +#include "CoreConfig.h" +#include "Element.h" +#include "Obstacle.h" +#include "SpatialQueries/ProximityQuery.h" +#include "MengeException.h" +#include + +namespace Menge { + + namespace Agents { + + /*! + * @brief Exception class for spatial query operations + */ + class MENGE_API SpatialQueryException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + SpatialQueryException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SpatialQueryException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal spatial query exception. + */ + class MENGE_API SpatialQueryFatalException : public SpatialQueryException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + SpatialQueryFatalException() : MengeException(), SpatialQueryException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SpatialQueryFatalException( const std::string & s ): MengeException(s), SpatialQueryException(), MengeFatalException() {} + }; + + // FORWARD DECLARATIONS + class BaseAgent; + + /*! + * @brief The base class for performing spatial queries. + * + * A spatial query implementation has to support several operations: + * - Given a maximum distance, find agents within that distance from a point + * - Given a maximum distance, find obstacles within that distance from a point + * - Given two points and a width, determines if a straight link + * between them is collision free (the link has the given width). + * - Updates its internal structure based on current agent state. + * // TODO: This should be done via a task. + * + * - The spatial query is also responsible for visiblity testing + * Spatial Queries work in tandem with a Filter. The query itself is agnostic of the filter or the results + */ + class MENGE_API SpatialQuery : public Element { + public: + /*! + * @brief Constructor. + */ + SpatialQuery(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~SpatialQuery() {} + + // Agent operations + public: + /*! + * @brief Define the set of agents on which query class will operate. + */ + virtual void setAgents( const std::vector< BaseAgent * > & agents ) = 0; + + /*! + * @brief Allows the spatial query structure to update its + * knowledge of the agent positions. + * TODO: Replace this with a task. + */ + virtual void updateAgents() = 0; + + /*! + * @brief adds an obstacle to the internal list of the spatial query + * + */ + virtual void addObstacle(Obstacle *obs); + + /*! + * @brief returns the collected obstacles of the spatial query for use in visualization + * @returns const pointer to the obstacle set + * + */ + const std::vector< Obstacle * > getObstacles() {return _obstacles;}; + + /*! + * @brief performs an agent based proximity query + * @param query a pointer for the proximity query to be performed + */ + virtual void agentQuery( ProximityQuery *query) const = 0; + + // Obstacle operations + + /*! + * @brief Do the necessary pre-computation to support obstacle + * definitions. Now uses the internal obstacle representation + */ + virtual void processObstacles() = 0; + + /*! + * @brief performs an obstacle based proximity query + * @param query a pointer for the proximity query to be performed + */ + virtual void obstacleQuery( ProximityQuery *query) const = 0; + + /*! + * @brief Queries the visibility between two points within a + * specified radius. + * @param q1 The first point between which visibility is + * to be tested. + * @param q2 The second point between which visibility is + * to be tested. + * @param radius The radius within which visibility is to be + * tested. + * @returns True if q1 and q2 are mutually visible within the radius; + * false otherwise. + */ + virtual bool queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const = 0; + + /*! + * @brief Sets the spatial query to include visibility in finding agent neighbors. + * + * @param state If true, the spatial query has to consider visibility. + * if false, it doesn't. + */ + virtual void setNeighborVisibleTest( bool state ) {} + + /*! + * @brief Sets the test visibility status of the neighbor functions. + * + * @param status The new stats of the test visibility property. + */ + inline void setTestVisibility( bool status ) { _testVisibility = status; } + + /*! + * @brief Reports the test visibility property of the spatial query instance. + * + * @returns A boolean reporting if the spatial query instance uses visibility + * tests when computing nearby agents and obstacles (true) or not (false). + */ + inline bool getTestVisibility() const { return _testVisibility; } + + protected: + /*! + * @brief Dictates if visibility queries should be used (true) for neighbor + * queries or not (false). + */ + bool _testVisibility; + + /*! + * @brief an internal central list of obstacles + * + */ + std::vector _obstacles; + }; + } // namespace Agents +} // namespace Menge +#endif // __SPATIAL_QUERY_H__ diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.cpp new file mode 100644 index 00000000..e9248441 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.cpp @@ -0,0 +1,67 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SpatialQueryDatabase.h" +#include "SpatialQueries/SpatialQueryKDTree.h" +#include "SpatialQueries/SpatialQueryNavMesh.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< Agents::SpatialQueryFactory, Agents::SpatialQuery >::getElementName() { return "spatial query"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< Agents::SpatialQueryFactory, Agents::SpatialQuery >::addBuiltins() { + addFactory( new Agents::BergKDTreeFactory() ); + addFactory( new Agents::NavMeshSpatialQueryFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.h new file mode 100644 index 00000000..4a5efa7a --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryDatabase.h @@ -0,0 +1,73 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQueryDatabase.h + * @brief Central database for querying available spatial query implementations. + * + * For spatial queries to be used in simulation, they must register + * themselves into the SpatialQueryDatabase. This is done via the PluginEngine. + */ + +#ifndef __SPATIAL_QUERY_DATABASE_H__ +#define __SPATIAL_QUERY_DATABASE_H__ + +#include "ElementDatabase.h" +#include "SpatialQueries/SpatialQueryFactory.h" +#include "SpatialQueries/SpatialQuery.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered spatial query implementations. + */ + typedef ElementDB< SpatialQueryFactory, SpatialQuery > SpatialQueryDB; + + } // namespace Agents + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< Agents::SpatialQueryFactory, Agents::SpatialQuery>::addBuiltins(); + template<> std::string ElementDB< Agents::SpatialQueryFactory, Agents::SpatialQuery >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __SPATIAL_QUERY_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.cpp new file mode 100644 index 00000000..7462e76b --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SpatialQueryFactory.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SpatialQueryFactory + ///////////////////////////////////////////////////////////////////// + + SpatialQueryFactory::SpatialQueryFactory(): ElementFactory< SpatialQuery >() { + // register attributes + _testVisID = _attrSet.addBoolAttribute( "test_visibility", false/*required*/, false/*default*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool SpatialQueryFactory::setFromXML( SpatialQuery * sQuery, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< SpatialQuery >::setFromXML( sQuery, node, behaveFldr ) ) return false; + + sQuery->setTestVisibility( _attrSet.getBool( _testVisID ) ); + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.h new file mode 100644 index 00000000..9172a4b8 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryFactory.h @@ -0,0 +1,97 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQueryFactory.h + * @brief The factory for parsing xml data and instantiating + * spaital query implementations. + */ + +#ifndef __SPATIAL_QUERY_FACTORY_H__ +#define __SPATIAL_QUERY_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "SpatialQueries/SpatialQuery.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class SpatialQuery; + + /*! + * @brief A class for parsing the xml description of a spatial query + * and instantiating particular instances. + */ + class MENGE_API SpatialQueryFactory : public ElementFactory< SpatialQuery > { + public: + /*! + * @brief Constructor. + */ + SpatialQueryFactory(); + + protected: + /*! + * @brief Given a pointer to a SpatialQuery instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this SpatialQuery's type. + * (i.e. SpatialQueryFactory::thisFactory has already been called and returned true.) + * If sub-classes of SpatialQueryFactory introduce *new* SpatialQuery parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param sQuery A pointer to the spatial query whose attributes are to be set. + * @param node The XML node containing the spatial query attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( SpatialQuery * sQuery, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "test_visibility" bool attribute. + */ + size_t _testVisID; + }; + } // namespace Agents +} // namespace Menge +#endif // __SPATIAL_QUERY_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryKDTree.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryKDTree.h new file mode 100644 index 00000000..3d26fa76 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryKDTree.h @@ -0,0 +1,197 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQueryKDTree.h + * @brief A spatial query object based on Jur van den Berg's kd-tree as defined + * in the RVO2 library (http://gamma.cs.unc.edu/RVO2). + * + * This spatial query implementation uses a kd-tree for agents and a bsp-tree for + * obstacles. The BSP Tree changes the input obstacle set. Single line segments can end + * up cut into two or more pieces. This *may* have a deleterious effect on simulation. + */ + +#ifndef __SPATIAL_QUERY_KD_TREE_H__ +#define __SPATIAL_QUERY_KD_TREE_H__ + +// UTILS +#include "SpatialQueries/SpatialQuery.h" +#include "SpatialQueries/SpatialQueryFactory.h" +#include "SpatialQueries/AgentKDTree.h" +#include "SpatialQueries/ObstacleKDTree.h" + +namespace Menge { + + namespace Agents { + + /*! + * @brief Spatial query object. Used to determine obstacles + * and agents near an agent -- based on a kd-tree. + */ + class MENGE_API BergKDTree : public SpatialQuery { + public: + /*! + * @brief Constructor. + */ + explicit BergKDTree(): SpatialQuery() { + } + + // Agent operations + + /*! + * @brief Define the set of agents on which kd-tree will query. + * + * @param agents The set of agents in the simulator to be managed. + */ + virtual void setAgents( const std::vector< BaseAgent * > & agents ) { + _agentTree.setAgents( agents ); + } + + /*! + * @brief Allows the spatial query structure to update its + * knowledge of the agent positions. + */ + virtual void updateAgents() { + _agentTree.buildTree(); + }; + + /*! + * @brief performs an agent based proximity query + * + * @param query a pointer to the proximity query to be performed + */ + virtual void agentQuery( ProximityQuery *query) const { + _agentTree.agentQuery(query); + } + + // Obstacle operations + + /*! + * @brief Do the necessary pre-computation to support obstacle + * definitions. + */ + virtual void processObstacles() { + _obstTree.buildTree( _obstacles ); + } + + /*! + * @brief perform an obstacle based proximity query + * + * @param query a pointer to the proximity query to be performed + * + */ + virtual void obstacleQuery( ProximityQuery *query) const { + _obstTree.obstacleQuery( query); + } + + /*! + * @brief Queries the visibility between two points within a + * specified radius. + * + * @param q1 The first point between which visibility is + * to be tested. + * @param q2 The second point between which visibility is + * to be tested. + * @param radius The radius within which visibility is to be + * tested. + * @returns True if q1 and q2 are mutually visible within the radius; + * false otherwise. + */ + virtual bool queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const { + return _obstTree.queryVisibility( q1, q2, radius ); + } + + protected: + /*! + * @brief A kd-tree for the agent queries. + */ + AgentKDTree _agentTree; + + /*! + * @brief A kd-tree for the obstacle queries. + */ + ObstacleKDTree _obstTree; + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the BergKDTree. + */ + class MENGE_API BergKDTreeFactory : public SpatialQueryFactory { + public: + /*! + * @brief The name of the spatial query implemenation. + * + * The spatial query's name must be unique among all registered + * spatial query components. Each spatial query factory must override + * this function. + * + * @returns A string containing the unique spatial query name. + */ + virtual const char * name() const { return "kd-tree"; } + + /*! + * @brief A description of the spatial query. + * + * Each spatial query factory must override this function. + * + * @returns A string containing the spatial query description. + */ + virtual const char * description() const { + return "Performs spatial queries by creating a kd-tree on the agents and a bsp " \ + "tree on the obstacles."; + }; + + protected: + /*! + * @brief Create an instance of this class's spatial query implementation. + * + * All SpatialQueryFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding spatial query type. The various field values + * of the instance will be set in a subsequent call to SpatialQueryFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated SpatialQuery class. + */ + SpatialQuery * instance() const { return new BergKDTree(); } + }; + } // namespace Agents +} // namespace Menge +#endif //__SPATIAL_QUERY_KD_TREE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.cpp b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.cpp new file mode 100644 index 00000000..189fb6d0 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.cpp @@ -0,0 +1,404 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SpatialQueryNavMesh.h" +#include "Tasks/NavMeshLocalizerTask.h" +#include "BaseAgent.h" +#include "NavMeshLocalizer.h" +#include "NavMeshEdge.h" +#include "NavMeshNode.h" +#include "os.h" +#include +#include +#include + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////// + // Implementation of HELPERS + //////////////////////////////////////////////////////////////// + + /*! + * @brief A visiblity cone. In order for an agent to be visible, they must lie + * within the visibility cone. + * + */ + class VisibilityCone { + public: + /*! + * @brief Constructor - the visiblity cone is defined by two vectors. + * The cone is assumed to be the smaller angle subtending the two + * vectors. The constructor orders them appropriately. + * + * @param dir0 One bound on the cone. + * @param dir1 The other bound on the cone. + */ + VisibilityCone( const Vector2 & dir0, const Vector2 & dir1 ) { + if ( det( dir0, dir1 ) > 0 ) { + _right = dir0; + _left = dir1; + } else { + _right = dir1; + _left = dir0; + } + } + + /*! + * @brief Reports if any portion of a line segment lies within the visibility cone. + * + * @param p0 One end of the line segment. + * @param p1 The other end of the line segment. + * @returns A boolean which indicates if any portion of the segment lies in the cone + * (true) and is visible, or if it lies outside and is not visible (false). + */ + bool isVisible( const Vector2 & p0, const Vector2 & p1 ) const { + // if either point is visible, then it is true + float right0 = det( p0, _right ); + float left0 = det( _left, p0 ); + if ( right0 <= 0 && left0 <= 0 ) return true; + + float right1 = det( p1, _right ); + float left1 = det( _left, p1 ); + if ( right1 <= 0 && left1 <= 0 ) return true; + + // otherwise, if the two points lie outside the cone on opposite sides + // then the cone intersects the center. + if ( right0 > 0 && left1 > 0 ) { + return det( p1 - p0, -p0 ) > 0.f; + } else if ( right1 > 0 && left0 > 0 ) { + return det( p0 - p1, -p1 ) > 0.f; + } + return false; + } + + /*! + * @brief Reports if the point lies within the visibility cone. + * + * @param p The point to test. + * @returns A boolean which indicates if the point lies in the cone (true) and + * is visible, or if it lies outside and is not visible (false). + */ + bool isVisible( const Vector2 & p ) const { + if ( det( p, _right ) > 0 ) return false; + if ( det( _left, p ) > 0 ) return false; + return true; + } + + /*! + * @brief Intersects this cone with the given cone, changing the extent + * of this cone to adhere to the intersected span. + * + * @param cone The cone to intersect this cone with. + * @returns A boolean reporting if there is a non-empty intersection (true) + * or if there is no proper intersection (false). + */ + bool intersect( const VisibilityCone & cone ) { + Vector2 iRight( det( _right, cone._right ) > 0 ? cone._right : _right ); + Vector2 iLeft( det( _left, cone._left ) > 0 ? _left : cone._left ); + if ( det( iRight, iLeft ) > 0 ) { + _right.set( iRight ); + _left.set( iLeft ); + return true; + } else { + return false; + } + } + + /*! + * @brief The left bound of the cone. + */ + Vector2 _left; + + /*! + * @brief the right bound of the cone. + */ + Vector2 _right; + }; + + + + /*! + * @brief An entry of a nav mesh node including the distance to + * the node. Used in the queue to search nearby nodes. + */ + class NeighborEntry { + public: + /*! + * @brief Constructor + * + * @param distSq The squared distance from some reference point + * to the nearest point on the mesh polygon. + * @param cone The visibility cone, in which all agents and portals must lie, + * to be considered viable candidates. + * @param nodeID The identifier of the navigation mesh node. + */ + NeighborEntry( float distSq, const VisibilityCone & cone, unsigned int nodeID ): _distSq(distSq), _cone(cone), _nodeID(nodeID) { + } + + /*! + * @brief Comparator - provided for creating a min_heap. + * + * @param entry The other entry against which to compare this entry. + * @returns True if the squared distance for this entry is less that of the given + * entry. + */ + bool operator<( const NeighborEntry & entry ) const { + return _distSq < entry._distSq; + } + + /*! + * @brief The squared distance from some reference point to the node. + */ + float _distSq; + + /*! + * @brief The cone of visibility in which all agents and portals must lie + * to be considered a viable candidate. + */ + VisibilityCone _cone; + + /*! + * @brief The identifier of the node. + */ + unsigned int _nodeID; + }; + + //////////////////////////////////////////////////////////////// + // Implementation of NavMeshSpatialQuery + //////////////////////////////////////////////////////////////// + + NavMeshSpatialQuery::NavMeshSpatialQuery():_localizer(0x0) { + } + + //////////////////////////////////////////////////////////////// + + void NavMeshSpatialQuery::setAgents( const std::vector< BaseAgent * > & agents ) { + _agents.insert( _agents.begin(), agents.begin(), agents.end() ); + } + + //////////////////////////////////////////////////////////////// + + void NavMeshSpatialQuery::agentQuery( ProximityQuery *filter ) const { + float range = filter->getMaxAgentRange(); + agentQuery(filter, range); + } + void NavMeshSpatialQuery::agentQuery( ProximityQuery *filter, float &rangeSq) const { + Vector2 pt = filter->getQueryPoint(); + unsigned int currNode = _localizer->getNode( pt); + assert( currNode != NavMeshLocation::NO_NODE && "Can't use NavMesh for spatial query if the point isn't on the mesh" ); + + // This does not need any synchronization elements + // The writing and the reading happen in two, independent computational + // stages. (i.e., the writing to the node occupancy happens in a task.) + // This is all read-only operations and can be done simultaneously. + const OccupantSet * occupants = _localizer->getNodeOccupants( currNode ); + if ( occupants->size() > 1 ) { + OccupantSetCItr itr = occupants->begin(); + for ( ; itr != occupants->end(); ++itr ) { + + const BaseAgent * candidate = _agents[ *itr ]; + float distSq = absSq( candidate->_pos - pt ); + if ( distSq <= rangeSq ) { + // NOTE: This call might change rangeSq; it may shrink based on the most distant neighbor + filter->filterAgent( candidate, distSq ); + + rangeSq = filter->getMaxAgentRange(); + } + + + } + } + + NavMeshPtr navMesh = _localizer->getNavMesh(); + // Track which nodes have been visited + std::set< unsigned int > visited; + visited.insert( (unsigned int) currNode ); + // now create a min heap of nearby navigation mesh nodes to explore for neighbor candidates + std::list< NeighborEntry > queue; + + // seed the queue with this node's adjacent nodes + const NavMeshNode & node = navMesh->getNode( (unsigned int)currNode ); + const size_t EDGE_COUNT = node.getEdgeCount(); + for ( size_t e = 0; e < EDGE_COUNT; ++e ) { + const NavMeshEdge * edge = node.getEdge( e ); + const NavMeshNode * otherNode = edge->getOtherByID( currNode ); + visited.insert( otherNode->getID() ); + float distSq = edge->getSqDist( pt ); + if ( distSq <= rangeSq ) { + queue.push_back( NeighborEntry( distSq, VisibilityCone( edge->getP0() - pt, edge->getP1() - pt ), otherNode->getID() ) ); + //cones.push_back( VisibilityCone( edge->getP0() - P, edge->getP1() - P ) ); + // edge is close enough that portions of the node are reachable + //queue.push_back( NeighborEntry( distSq, otherNode->getID() ) ); + } + } + + while ( queue.size() > 0 ) { + NeighborEntry nbrEntry = *(queue.begin()); + queue.pop_front(); + if ( nbrEntry._distSq > rangeSq ) continue; + + const OccupantSet * occupants = _localizer->getNodeOccupants( nbrEntry._nodeID ); + if ( occupants->size() > 0 ) { + OccupantSetCItr itr = occupants->begin(); + for ( ; itr != occupants->end(); ++itr ) { + const BaseAgent * candidate = _agents[ *itr ]; + Vector2 disp( candidate->_pos - pt ); + float distSq = absSq( disp ); + if ( distSq <= rangeSq ) { + if ( nbrEntry._cone.isVisible( disp ) ) { + filter->filterAgent( candidate, distSq ); + } + + rangeSq = filter->getMaxAgentRange(); + + } + + } + } + + const NavMeshNode & node = navMesh->getNode( nbrEntry._nodeID ); + const size_t EDGE_COUNT = node.getEdgeCount(); + for ( size_t e = 0; e < EDGE_COUNT; ++e ) { + const NavMeshEdge * edge = node.getEdge( e ); + + const NavMeshNode * otherNode = edge->getOtherByID( nbrEntry._nodeID ); + if ( visited.find( otherNode->getID() ) != visited.end() ) continue; + visited.insert( otherNode->getID() ); + + float distSq = edge->getSqDist(pt ); + if ( distSq <= rangeSq ) { + Vector2 disp1 = edge->getP0() - pt; + Vector2 disp2 = edge->getP1() - pt; + VisibilityCone cone( disp1, disp2 ); + if ( cone.intersect( nbrEntry._cone ) ) { + queue.push_back( NeighborEntry( distSq, cone, otherNode->getID() ) ); + } + } + } + } + } + + //////////////////////////////////////////////////////////////// + + bool NavMeshSpatialQuery::queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const { + return true; + } + + //////////////////////////////////////////////////////////////// + + void NavMeshSpatialQuery::processObstacles() { + // Compute obstacle convexity -- this assumes all closed polygons + NavMeshPtr navMesh = _localizer->getNavMesh(); + const unsigned int OBST_COUNT = static_cast< unsigned int >( navMesh->getObstacleCount() ); + for ( unsigned int o = 0; o < OBST_COUNT; ++o ) { + NavMeshObstacle & obst = navMesh->getObstacle( o ); + if ( obst._prevObstacle ) { + obst._isConvex = leftOf( obst._prevObstacle->getP0(), obst.getP0(), obst.getP1() ) >= 0; + } else { + obst._isConvex = true; + } + } + } + + //////////////////////////////////////////////////////////////// + void NavMeshSpatialQuery::obstacleQuery( ProximityQuery *filter) const { + float range = filter->getMaxObstacleRange(); + obstacleQuery(filter, range); + } + + void NavMeshSpatialQuery::obstacleQuery( ProximityQuery *filter, float rangeSq ) const { + Vector2 pt = filter->getQueryPoint(); + size_t currNode = _localizer->getNode( pt ); + + assert( currNode != NavMeshLocation::NO_NODE && "Can't use NavMesh for spatial query if the point isn't on the mesh" ); + + const NavMeshPtr navMesh = _localizer->getNavMesh(); + const NavMeshNode & node = navMesh->getNode( (unsigned int)currNode ); + const size_t OBST_COUNT = node.getObstacleCount(); + for ( size_t o = 0; o < OBST_COUNT; ++o ) { + const NavMeshObstacle * obst = node.getObstacle( o ); + if ( obst->pointOutside( pt ) ) { + float distance = distSqPointLineSegment(obst->getP0(), obst->getP1(), pt); + filter->filterObstacle( obst, distance ); + } + } + + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * NavMeshSpatialQuery::getTask() { + return new BFSM::NavMeshLocalizerTask( _localizer->getNavMesh()->getName(), false /*usePlanner*/ ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshVCFactory + ///////////////////////////////////////////////////////////////////// + + NavMeshSpatialQueryFactory::NavMeshSpatialQueryFactory() : SpatialQueryFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool NavMeshSpatialQueryFactory::setFromXML( SpatialQuery * sq, TiXmlElement * node, const std::string & specFldr ) const { + NavMeshSpatialQuery * nmsq = dynamic_cast< NavMeshSpatialQuery * >( sq ); + assert( nmsq != 0x0 && "Trying to set attributes of a navigation mesh spatial query component on an incompatible object" ); + + if ( ! SpatialQueryFactory::setFromXML( nmsq, node, specFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, specFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh localizer + NavMeshLocalizerPtr nmlPtr; + try { + nmlPtr = loadNavMeshLocalizer( fName, true ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh localizer required by the spatial query on line " << node->Row() << "."; + return false; + } + nmsq->setNavMeshLocalizer( nmlPtr ); + + return true; + } + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.h new file mode 100644 index 00000000..c6785fc2 --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryNavMesh.h @@ -0,0 +1,245 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQueryNavMesh.h + * @brief Definition of a spatial query structure based on a navigation mesh. + */ + +#ifndef __SPATIAL_QUERY_NAV_MESH_H__ +#define __SPATIAL_QUERY_NAV_MESH_H__ + +// Menge Base +#include "SpatialQueries/SpatialQuery.h" +#include "SpatialQueries/SpatialQueryFactory.h" + +// Resources +#include "NavMesh.h" +#include "NavMeshLocalizer.h" + +// STL +#include + +namespace Menge { + + // forward declaration + namespace BFSM { + class Task; + } + + namespace Agents { + + /*! + * @brief A spatial query structure based on a navigation mesh. + */ + class MENGE_API NavMeshSpatialQuery : public SpatialQuery { + public: + /*! + * @brief Constructor. + */ + NavMeshSpatialQuery(); + + /*! + * @brief Define the set of agents on which kd-tree will query. + */ + virtual void setAgents( const std::vector< BaseAgent * > & agents ); + + /*! + * @brief Allows the spatial query structure to update its + * knowledge of the agent positions. + * + * This happens by the NavMeshLocalizer as an FSM task. + */ + virtual void updateAgents() {} + + /*! + * @brief gets agents within a range, and passes them to the supplied filter + * @param query a pointer to the proximity query to be performed + */ + virtual void agentQuery( ProximityQuery *query) const; + + /*! + * @brief performs an agent based proximity query + * + * @param query a pointer to the proximity query to be performed + * @param rangeSq the range to search (extracted and mutable) + */ + virtual void agentQuery( ProximityQuery *query, float &rangeSq) const; + + // Obstacle operations + + /*! + * @brief Do the necessary pre-computation to support obstacle + * definitions. + */ + virtual void processObstacles(); + + /*! + * @brief performs an obstacle based proximity query + * @param query a pointer to the proximity query to be performed + */ + virtual void obstacleQuery( ProximityQuery *query) const; + + /*! + * @brief performs an obstacle based proximity query + * @param query a pointer to the proximity query to be performed + * @param rangeSq the range to search (extracted and mutable) + */ + virtual void obstacleQuery( ProximityQuery *query, float rangeSq) const; + + + /*! + * @brief Queries the visibility between two points within a + * specified radius. NOT CURRENTLY IMPLEMENTED! + * @param q1 The first point between which visibility is + * to be tested. + * @param q2 The second point between which visibility is + * to be tested. + * @param radius The radius within which visibility is to be + * tested. + * @returns True if q1 and q2 are mutually visible within the radius; + * false otherwise. + */ + virtual bool queryVisibility(const Vector2& q1, const Vector2& q2, float radius) const; + + /*! + * @brief Sets the navigation mesh localizer pointer. + * + * @param nml The managed pointer to the navigation mesh localizer. + */ + void setNavMeshLocalizer( const NavMeshLocalizerPtr & nml ) { _localizer = nml; } + + /*! + * @brief Returns a pointer to the nav mesh localizer task. + * + * @returns A pointer to the nav mesh localizer task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual BFSM::Task * getTask(); + + // TODO: Another version of this would be good where the inputs are an agent, and + // a point, and it uses the agent's position and radius. + protected: + + /*! + * @brief A vector of pointers to all the agents in the simulation + */ + std::vector< BaseAgent * > _agents; + + /*! + * @brief The localizer tied to the given navigation mesh. + */ + NavMeshLocalizerPtr _localizer; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the NavMeshSpatialQuery. + */ + class MENGE_API NavMeshSpatialQueryFactory : public SpatialQueryFactory { + public: + /*! + * @brief Constructor. + */ + NavMeshSpatialQueryFactory(); + + /*! + * @brief The name of the spatial query implemenation. + * + * The spatial query's name must be unique among all registered + * spatial query components. Each spatial query factory must override + * this function. + * + * @returns A string containing the unique spatial query name. + */ + virtual const char * name() const { return "nav_mesh"; } + + /*! + * @brief A description of the spatial query. + * + * Each spatial query factory must override this function. + * + * @returns A string containing the spatial query description. + */ + virtual const char * description() const { + return "Performs spatial queries by operating on a navigation mesh."; + }; + + protected: + /*! + * @brief Create an instance of this class's spatial query implementation. + * + * All SpatialQueryFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding spatial query type. The various field values + * of the instance will be set in a subsequent call to SpatialQueryFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated SpatialQuery class. + */ + SpatialQuery * instance() const { return new NavMeshSpatialQuery(); } + + /*! + * @brief Given a pointer to an SpatialQuery instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this SpatialQuery's type. + * (i.e. SpatialQueryFactory::thisFactory has already been called and returned true.) + * If sub-classes of SpatialQueryFactory introduce *new* SpatialQuery parameters, + * then the sub-class should override this method but explicitly call the parent + * class's version. + * + * @param sq A pointer to the spatial query whose attributes are to be set. + * @param node The XML node containing the elevation attributes. + * @param specFldr The path to the specification file. If the SpatialQuery + * references resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( SpatialQuery * sq, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; + } // namespace Agents +} // namespace Menge +#endif // __SPATIAL_QUERY_NAV_MESH_H__ diff --git a/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryStructs.h b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryStructs.h new file mode 100644 index 00000000..8ca1c35c --- /dev/null +++ b/src/Menge/MengeCore/Agents/SpatialQueries/SpatialQueryStructs.h @@ -0,0 +1,109 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SpatialQueryStructs.h + * @brief Structs for storing results from spatial queries + */ + +#ifndef __SPATIAL_QUERY_STRUCTS_H__ +#define __SPATIAL_QUERY_STRUCTS_H__ + + +// UTILS +#include "CoreConfig.h" +#include +#include + +namespace Menge { + + namespace Agents { + + //forward declaration + class BaseAgent; + class Obstacle; + + /*! + * @brief struct to store agent proximity query results. + */ + struct NearAgent { + /*! + * @brief distanceSquared to the agent + */ + float distanceSquared; + + /*! + * @brief the agent pointer + */ + const BaseAgent * agent; + + /*! + * @brief constructor + * + * @param distance the distance to store in the struct + * @param agt the agent to store in the struct + */ + NearAgent(float distance, const BaseAgent * agt):distanceSquared(distance),agent(agt){}; + }; + + /*! + * @brief struct to store obstacle proximity query results. + */ + struct NearObstacle{ + /*! + * @brief distanceSquared to the obstacle + */ + float distanceSquared; + + /*! + * @brief pointer to the obstacle + */ + const Obstacle * obstacle; + + /*! + * @brief constructor + * + * @param distance the distance to store in the struct + * @param obs the obstacle to store in the struct + */ + NearObstacle(float distance, const Obstacle * obs):distanceSquared(distance),obstacle(obs){}; + }; + + } // namespace Agents +} // namespace Menge +#endif \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.cpp b/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.cpp new file mode 100644 index 00000000..baf76adf --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.cpp @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ConstStateSelector.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ConstProfileSelectorFactory + //////////////////////////////////////////////////////////////////////////// + + ConstStateSelectorFactory::ConstStateSelectorFactory() : StateSelectorFactory() { + _nameID = _attrSet.addStringAttribute( "name", true, "" ); + } + + //////////////////////////////////////////////////////////////////////////// + + bool ConstStateSelectorFactory::setFromXML( StateSelector * sel, TiXmlElement * node, const std::string & specFldr ) const { + ConstStateSelector * cSel = dynamic_cast< ConstStateSelector * >( sel ); + assert( cSel != 0x0 && "Trying to set attributes of a const state selector element on an incompatible object" ); + + if ( ! StateSelectorFactory::setFromXML( cSel, node, specFldr ) ) return false; + + cSel->setStateName( _attrSet.getString( _nameID ) ); + + return true; + } + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.h b/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.h new file mode 100644 index 00000000..6cc7771a --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/ConstStateSelector.h @@ -0,0 +1,163 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ConstStateSelector.h + * @brief The definition of a state selector that assigns all agents + * the same initial state. + */ + +#ifndef __CONST_STATE_SELECTOR_H__ +#define __CONST_STATE_SELECTOR_H__ + +#include "mengeCommon.h" +#include "StateSelectors/StateSelector.h" +#include "StateSelectors/StateSelectorFactory.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief An initial state selector that stores a single state + * and assigns that state to all agents. + */ + class MENGE_API ConstStateSelector : public StateSelector { + public: + /*! + * @brief Constructor. + */ + ConstStateSelector() : _stateName("") {} + + /*! + * @brief Provides the name of a state. + * + * Ths must be overriden by child classes. + * + * @returns: The name of the state. + */ + virtual std::string getState() { return _stateName; } + + /*! + * @brief Sets the name of the state. + * + * @param name The name of the selector's state. + */ + void setStateName( const std::string & name ) { _stateName = name; } + + protected: + /*! + * @brief The name of the profile to use. + */ + std::string _stateName; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for the ConstStateSelector. + */ + class MENGE_API ConstStateSelectorFactory : public StateSelectorFactory { + public: + /*! + * @brief Constructor + */ + ConstStateSelectorFactory(); + + /*! + * @brief The name of the state selector type. + * + * The state selector's name must be unique among all registered state selector elements. + * Each state selector factory must override this function. + * + * @returns A string containing the unique state selector name. + */ + virtual const char * name() const { return "const"; } + + /*! + * @brief A description of the state selector. + * + * Each state selector factory must override this function. + * + * @returns A string containing the state selector description. + */ + virtual const char * description() const { + return "State selector which assigns the initial state to all agents."; + }; + + protected: + /*! + * @brief Create an instance of this class's state selector implementation. + * + * All StateSelectorFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding selector type. The various field values + * of the instance will be set in a subsequent call to StateSelectorFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated StateSelector class. + */ + StateSelector * instance() const { return new ConstStateSelector(); } + + /*! + * @brief Given a pointer to a StateSelector instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this StateSelector's type. + * (i.e. StateSelectorFactory::thisFactory has already been called and returned true.) + * If sub-classes of StateSelectorFactory introduce *new* StateSelector parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param sel A pointer to the state selector whose attributes are to be set. + * @param node The XML node containing the goal attributes. + * @param specFldr The path to the specification file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( StateSelector * sel, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "name" string parameter. + */ + size_t _nameID; + }; + + } // namespace Agents +} // namespace Menge +#endif // __CONST_STATE_SELECTOR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.cpp b/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.cpp new file mode 100644 index 00000000..c95c6e76 --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.cpp @@ -0,0 +1,58 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateSelectors/StateSelector.h" + +namespace Menge { + + namespace Agents { + + ///////////////////////////////////////////////////////////////////// + // Implementation of StateSelector + ///////////////////////////////////////////////////////////////////// + + StateSelector::StateSelector(): Element() { + } + + ///////////////////////////////////////////////////////////////////// + + StateSelector::~StateSelector() { + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.h b/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.h new file mode 100644 index 00000000..74b2308b --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/StateSelector.h @@ -0,0 +1,124 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateSelector.h + * @brief The definition of the agent initial state selector element. + * This is the mechanism which determines which state in the FSM the agent starts in. + */ +#ifndef __STATE_SELECTOR_H__ +#define __STATE_SELECTOR_H__ + +#include "mengeCommon.h" +#include "Element.h" + +namespace Menge { + + namespace Agents { + // forward declaration + class BaseAgent; + + /*! + * @brief Exception class for state selector computation. + */ + class MENGE_API StateSelectorException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + StateSelectorException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + StateSelectorException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal state selector exception. + */ + class MENGE_API StateSelectorFatalException : public StateSelectorException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + StateSelectorFatalException() : MengeException(), StateSelectorException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + StateSelectorFatalException( const std::string & s ): MengeException(s), StateSelectorException(), MengeFatalException() {} + }; + + /*! + * @brief The base class for selecting an agent's intial state. + * + * This is an abstract class, primarily defining the mechanism for selecting + * an agent's initial state. + */ + class MENGE_API StateSelector : public Element { + public: + /*! + * @brief Constructor + */ + StateSelector(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~StateSelector(); + + public: + /*! + * @brief Provides the name of a state. + * + * Ths must be overriden by child classes. + * + * @returns: The name of the state. + */ + virtual std::string getState() = 0; + }; + + } // namespace Agents +} // namespace Menge +#endif // __PROFILE_SELECTOR_H__ diff --git a/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.cpp b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.cpp new file mode 100644 index 00000000..22f14071 --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateSelectorDatabase.h" +#include "StateSelectors/ConstStateSelector.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + /*! + * @brief Reports the database name. + * + * @returns The string representation of the database name. + */ + template <> + std::string ElementDB< Agents::StateSelectorFactory, Agents::StateSelector >::getElementName() { return "initial state selector"; } + + /*! + * @brief Initialization of built in database elements. + */ + template <> + void ElementDB< Agents::StateSelectorFactory, Agents::StateSelector >::addBuiltins() { + addFactory( new Agents::ConstStateSelectorFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.h b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.h new file mode 100644 index 00000000..586958d4 --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorDatabase.h @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateSelectorDatabase.h + * @brief Central database for querying available profile selector implementations. + * + * For profile selectors to be used in simulation, they must register + * themselves into the ProfileSelectorDatabase. This is done via the PluginEngine. + */ + +#ifndef __STATE_SELECTOR_DATABASE_H__ +#define __STATE_SELECTOR_DATABASE_H__ + +#include "ElementDatabase.h" +#include "StateSelectors/StateSelectorFactory.h" +#include "StateSelectors/StateSelector.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief The database of registered state selector implementations. + */ + typedef ElementDB< StateSelectorFactory, StateSelector > StateSelectorDB; + + } // namespace Agents + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< Agents::StateSelectorFactory, Agents::StateSelector >::addBuiltins(); + template<> std::string ElementDB< Agents::StateSelectorFactory, Agents::StateSelector >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge +#endif // __STATE_SELECTOR_DATABASE_H__ diff --git a/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorFactory.h b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorFactory.h new file mode 100644 index 00000000..b762707a --- /dev/null +++ b/src/Menge/MengeCore/Agents/StateSelectors/StateSelectorFactory.h @@ -0,0 +1,63 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateSelectorFactory.h + * @brief The factory for parsing xml data and instantiating + * profile selector implementations. + */ + +#ifndef __STATE_SELECTOR_FACTORY_H__ +#define __STATE_SELECTOR_FACTORY_H__ + +#include "CoreConfig.h" +#include "ElementFactory.h" +#include "StateSelectors/StateSelector.h" + +namespace Menge { + + namespace Agents { + /*! + * @brief A class for parsing the xml description of an initial state selector element + * and instantiating particular instances. + */ + class MENGE_API StateSelectorFactory : public ElementFactory< StateSelector > { + }; + } // namespace Agents +} // namespace Menge +#endif // __STATE_SELECTOR_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/XMLSimulatorBase.cpp b/src/Menge/MengeCore/Agents/XMLSimulatorBase.cpp new file mode 100644 index 00000000..daa2ae45 --- /dev/null +++ b/src/Menge/MengeCore/Agents/XMLSimulatorBase.cpp @@ -0,0 +1,61 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "XMLSimulatorBase.h" +#include "SimulatorState.h" + +namespace Menge { + + namespace Agents { + + //////////////////////////////////////////////////////////////////// + // Implementation of XMLSimulatorBase + //////////////////////////////////////////////////////////////////// + + XMLSimulatorBase::XMLSimulatorBase() { + _initState = new SimulatorState(); + } + + //////////////////////////////////////////////////////////////////// + + XMLSimulatorBase::~XMLSimulatorBase() { + delete _initState; + } + + } // namespace Agents +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Agents/XMLSimulatorBase.h b/src/Menge/MengeCore/Agents/XMLSimulatorBase.h new file mode 100644 index 00000000..4733863b --- /dev/null +++ b/src/Menge/MengeCore/Agents/XMLSimulatorBase.h @@ -0,0 +1,253 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file XMLSimulatorBase.h + * @brief The set of operations used by SimXMLLoader to apply + * XML-parsed experiment specification to a simulator. + * + * In order to use the SimXMLLoader class to read XML files and set parameters + * The simulator must extend this abstract class and implement the given + * virtual functions. + * + */ + +#ifndef __XML_SIMULATOR_BASE__ +#define __XML_SIMULATOR_BASE__ + +#include "SimXMLLoader.h" +#include "mengeCommon.h" +#include + +namespace Menge { + + namespace Agents { + + class Elevation; + class SpatialQuery; + class BaseAgent; + class SimulatorState; + + #ifdef _MSC_VER + /*! + * This is visual studio non-ansi compliant functionality + * It doesnt like functions which declare specific types of exceptions thrown + * This turns off the silly visual studio warning. + */ + #pragma warning( disable : 4290 ) + #endif + + /*! + * @brief Exception for invalid parameters from XML specification. + */ + class MENGE_API XMLParamException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + XMLParamException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + XMLParamException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the xml parameter parser has an error which cannot be + * recovered from. + */ + class XMLParamFatalException : public XMLParamException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + XMLParamFatalException() : MengeException(), XMLParamException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + XMLParamFatalException( const std::string & s ): MengeException(s), XMLParamException(), MengeFatalException() {} + }; + + /*! + * @brief The base class for extracting simulator settings from the XML + * specification. + * + * In order to use the SimXMLLoader class to read XML files and set parameters + * The simulator must extend this abstract class and implement the given + * virtual functions. + * + * A "target"-specific parameter refers to the simulator type. In other words, + * If a simulator expects particular parameters, there should be a tag with + * the target name and a list of parameter values. The functionality of this + * class defines that functionality. + */ + class MENGE_API XMLSimulatorBase { + public: + /*! + * @brief Constructor. + */ + XMLSimulatorBase(); + + /*! + * @brief Destructor. + */ + ~XMLSimulatorBase(); + + /*! + * @brief Reports if there are any target-specific *experiment* parameters. + * + * The default case is to assume that the simulator *does* have particular + * parameters. + * + * @returns True if this simulator has target-specific *experiment* parameters, + * false otherwise. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Given the name of a tag which is the child of \, + * reports if it contains target-specific experiment parameters. + * + * It is guaranteed that the labels "AgentSet" and "Obstacle" will never + * be given as input. + * + * @param tagName The name of the candidate experiment XML tag. + * @returns True if the given tag corresponds to the unique tag defined + * for this simulator (and that tag's parameters should be + * applied to this simulator), false if not. + */ + virtual bool isExpTarget( const std::string & tagName ) = 0; + + /*! + * @brief Given the name of the xml param and its string value, + * sets the parameter in the simulator. + * + * Common parameters and target-specific parameters will be passed into this function. + * It is the responsibility of the programmer to make sure the default case of + * any parameter should fall through to the SimulatorBase::setExpParam function. + * + * @param paramName The name of the XML parameter. + * @param value The string representation of the parameter value. + * It is the responsibility of the particular sub-class to + * translate the representation as necessary. + * @returns True if the parameter was set successfully, false otherwise. + * @throws An XMLParamException if there was a problem with the parameter name/value + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( XMLParamException ) = 0; + + /*! + * @brief Add an agent with specified position to the simulator whose properties + * are defined by the given agent initializer. + * + * It uses the agent initializer to define the values of the remaining agent parameters + * + * @param pos The 2d vector representing the agent's position + * @param agentInit The AgentInitializer necessary to parse AgentSet properties + * @returns A pointer to the agent (if initialization was succesful) or NULL if failed. + */ + virtual BaseAgent * addAgent( const Vector2 & pos, AgentInitializer * agentInit ) = 0; + + /*! + * @brief Set the elevation instance of the simulator + * + * @param elevation The elevation object. + */ + virtual void setElevationInstance( Elevation * elevation ) = 0; + + /*! + * @brief Reports if the elevation has been set. + * + * @returns True if the elevation has been set, false otherwise. + */ + virtual bool hasElevation() const = 0; + + /*! + * @brief Sets the spatial query instance of the simulator. + * + * @param spatialQuery The spatial query object. + */ + virtual void setSpatialQuery( SpatialQuery * spatialQuery ) = 0; + + /*! + * @brief Gets the spatial query instance of the simulator. + * + * @returns pointer to The spatial query object. + */ + virtual SpatialQuery * getSpatialQuery() = 0; + + /*! + * @brief Reports if the spatial query has been set. + * + * @returns True if the elevation has been set, false otherwise. + */ + virtual bool hasSpatialQuery() const = 0; + + /*! + * @brief Initalize spatial query structure. + */ + virtual bool initSpatialQuery() = 0; + + /*! + * @brief After all agents and all obstacles have been added to the scene + * does the work to finish preparing the simulation to be run. + */ + virtual void finalize() {}; + + /*! + * @brief Returns a pointer to the simulator's initial state. + * + * @returns A pointer to the intial state. + */ + SimulatorState * getInitialState() { return _initState; } + + protected: + /*! + * @brief The initial state of the simulator. + */ + SimulatorState * _initState; + }; + } // namespace Agents +} // namespace Menge +#endif // __XML_SIMULATOR_BASE__ diff --git a/src/Menge/MengeCore/BFSM/Actions/Action.cpp b/src/Menge/MengeCore/BFSM/Actions/Action.cpp new file mode 100644 index 00000000..adfd7c03 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/Action.cpp @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Action.h" +#include "ActionDatabase.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Action + ///////////////////////////////////////////////////////////////////// + + void Action::onLeave( Agents::BaseAgent * agent ) { + if ( _undoOnExit ) { + leaveAction( agent ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of parsing function + ///////////////////////////////////////////////////////////////////// + + Action * parseAction( TiXmlElement * node, const std::string & behaveFldr ) { + return ActionDB::getInstance( node, behaveFldr ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/Action.h b/src/Menge/MengeCore/BFSM/Actions/Action.h new file mode 100644 index 00000000..9f75db6d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/Action.h @@ -0,0 +1,141 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Action.h + * @brief The definition of actions that are taken as agents enter states. + * + * Actions are associated with behavior states. When an agent enters the corresponding + * behavior state, the action is taken on the agent. It is typically used to modify + * agent parameters, consistent with what the state represents. By default the agent + * should restore the agents parameter values when the agent leaves the FSM state. + * However, a flag can deactivate this behavior. + */ + +#ifndef __ACTION_H__ +#define __ACTION_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "FSMEnumeration.h" +#include "Element.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + /*! + * @namespace BFSM + * @brief The namespace contains the Behavior Finite State Machine (BFSM) definition + */ + namespace BFSM { + + // forward declaration + class ActionFactory; + + /*! + * @brief The abstract definition of an action. + * + * An action is explicitly executed upon entering a state and has the + * option of undoing its effect upon exiting the state. + */ + class MENGE_API Action : public Element { + public: + /*! + * @brief Constructor. + */ + Action(): Element(), _undoOnExit(true){} + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~Action(){} + + public: + /*! + * @brief Upon entering the state, this is called -- it is the main work + * of the action. + * + * This is a purely virtual function. Any instantiable Action sub-class + * must *explicitly* account for this function. + * + * @param agent The agent to act on. + */ + virtual void onEnter( Agents::BaseAgent * agent ) = 0; + + /*! + * @brief The work to do upon state exit. + * + * @param agent The agent to act on. + */ + void onLeave( Agents::BaseAgent * agent ); + + friend class ActionFactory; + + protected: + /*! + * @brief The actual work to do upon exiting the state. + * + * This is a purely virtual function. Any Action sub-class must + * *explicitly* account for this function. It will only be called if the + * action is set to undo its work upon exit. + * + * @param agent The agent to act on. + */ + virtual void leaveAction( Agents::BaseAgent * agent ) = 0; + + /*! + * @brief Determines if the action undoes itself on exiting the state. + */ + bool _undoOnExit; + }; + + /*! + * @brief Parses a TinyXML element containing an action specification + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new action . + */ + Action * parseAction( TiXmlElement * node, const std::string & behaveFldr ); + } // namespace BFSM +} // namespace Menge +#endif // __ACTION_H__ diff --git a/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.cpp b/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.cpp new file mode 100644 index 00000000..48d529e2 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.cpp @@ -0,0 +1,63 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ActionDatabase.h" +#include "Actions/ObstacleAction.h" +#include "Actions/PropertyAction.h" +#include "Actions/TeleportAction.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + template <> + std::string ElementDB< BFSM::ActionFactory, BFSM::Action >::getElementName(){ return "action"; } + + template <> + void ElementDB< BFSM::ActionFactory, BFSM::Action >::addBuiltins() { + addFactory( new BFSM::RemoveObstacleActFactory() ); + addFactory( new BFSM::AddObstacleyActFactory() ); + addFactory( new BFSM::SetObstacleActFactory() ); + addFactory( new BFSM::SetPropertyActFactory() ); + addFactory( new BFSM::OffsetPropertyActFactory() ); + addFactory( new BFSM::ScalePropertyActFactory() ); + addFactory( new BFSM::TeleportActFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.h b/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.h new file mode 100644 index 00000000..74ace35e --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ActionDatabase.h @@ -0,0 +1,81 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ActionDatabase.h + * @brief Central database for querying available behavior actions. + * + * For actions to be used in the finite state machine, they must register + * themselves into the ActionDatabase. This is done via the PluginEngine. + */ + +#ifndef __ACTION_DATABASE_H__ +#define __ACTION_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Actions/ActionFactory.h" +#include "Actions/Action.h" + +namespace Menge { + + namespace BFSM { + + /*! + * @brief The database of registered action implementations. + */ + typedef ElementDB< ActionFactory, Action > ActionDB; + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + /*! + * @brief Explicit specialization of addBuiltins for the Action Database + */ + template<> void ElementDB< BFSM::ActionFactory, BFSM::Action >::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the Action Database + */ + template<> std::string ElementDB< BFSM::ActionFactory, BFSM::Action >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +// Declarations of explicit specialization + +#endif // __ACTION_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/Actions/ActionFactory.cpp b/src/Menge/MengeCore/BFSM/Actions/ActionFactory.cpp new file mode 100644 index 00000000..cc5bb093 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ActionFactory.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ActionFactory.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ActionFactory + ///////////////////////////////////////////////////////////////////// + + ActionFactory::ActionFactory(): ElementFactory< Action >() { + // register attributes + _exitResetID = _attrSet.addBoolAttribute( "exit_reset", false/*required*/, true/*default*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ActionFactory::setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< Action >::setFromXML( action, node, behaveFldr ) ) return false; + + action->_undoOnExit = _attrSet.getBool( _exitResetID ); + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/ActionFactory.h b/src/Menge/MengeCore/BFSM/Actions/ActionFactory.h new file mode 100644 index 00000000..10f74466 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ActionFactory.h @@ -0,0 +1,98 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ActionFactory.h + * @brief The factory for parsing xml data and instantiating + * actions. + */ + +#ifndef __ACTION_FACTORY_H__ +#define __ACTION_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "Actions/Action.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of an action + * and instantiating particular instances. + */ + class MENGE_API ActionFactory : public ElementFactory< Action > { + public: + /*! + * @brief Constructor. + */ + ActionFactory(); + + protected: + /*! + * @brief Given a pointer to an Action instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Action's type. + * (i.e. ActionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ActionFactory introduce *new* Action parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param action A pointer to the action whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "exit_reset" boolean attribute. + */ + size_t _exitResetID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __ACTION_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.cpp b/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.cpp new file mode 100644 index 00000000..d3189d35 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.cpp @@ -0,0 +1,126 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Actions/ObstacleAction.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ObstacleAction + ///////////////////////////////////////////////////////////////////// + + ObstacleAction::ObstacleAction():Action(), _setOperand(0),_originalMap() { + } + + ///////////////////////////////////////////////////////////////////// + + ObstacleAction::~ObstacleAction() { + // Is this delete safe? This may require a destroy method if it is + // instantiated in MengeCore and used in external dll + _originalMap.clear(); + } + + ///////////////////////////////////////////////////////////////////// + + void ObstacleAction::onEnter( Agents::BaseAgent * agent ) { + _lock.lock(); + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_obstacleSet; + agent->_obstacleSet = newValue( agent->_obstacleSet ); + _lock.release(); + } + + ///////////////////////////////////////////////////////////////////// + + void ObstacleAction::leaveAction( Agents::BaseAgent * agent ) { + _lock.lock(); + std::map< size_t, size_t >::iterator itr = _originalMap.begin(); + assert( itr != _originalMap.end() && "Trying to find an original value for an agent whose value was not cached" ); + agent->_obstacleSet = itr->second; + _originalMap.erase( itr ); + _lock.release(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ObstacleActFactory + ///////////////////////////////////////////////////////////////////// + + ObstacleActFactory::ObstacleActFactory():ActionFactory() { + _operandID = _attrSet.addSizeTAttribute( "operand", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ObstacleActFactory::setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const { + ObstacleAction * oAction = dynamic_cast< ObstacleAction * >( action ); + assert( oAction != 0x0 && "Trying to set obstacle set action properties on an incompatible object" ); + + if ( ! ActionFactory::setFromXML( action, node, behaveFldr ) ) return false; + oAction->_setOperand = _attrSet.getSizeT( _operandID ); + + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of RemoveObstacleSetAction + ///////////////////////////////////////////////////////////////////// + + size_t RemoveObstacleSetAction::newValue( size_t value ) { + return value & (~_setOperand); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of AddObstacleSetAction + ///////////////////////////////////////////////////////////////////// + + size_t AddObstacleSetAction::newValue( size_t value ) { + return value | _setOperand; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SetObstacleSetAction + ///////////////////////////////////////////////////////////////////// + + size_t SetObstacleSetAction::newValue( size_t value ) { + return _setOperand; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.h b/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.h new file mode 100644 index 00000000..99fda1d8 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/ObstacleAction.h @@ -0,0 +1,365 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ObstacleAction.h + * @brief Defines a set of BFSM actions that change agent + * obstacle set value. + */ + +#ifndef __OBSTACLE_ACTION_H__ +#define __OBSTACLE_ACTION_H__ + +#include "CoreConfig.h" +#include "Action.h" +#include "Actions/ActionFactory.h" +#include "fsmCommon.h" +#include "FSMEnumeration.h" +#include +#include "SimpleLock.h" + +// forward declaration + +namespace Menge { + + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + // forward declaration + class ObstacleActFactory; + + /*! + * @brief The base class for modifying agent obstacle sets. + * + * This is an abstract class and must be sub-classed. + */ + class MENGE_API ObstacleAction : public Action { + public: + /*! + * @brief Constructor + */ + ObstacleAction(); + + /*! + * @brief Virtual destructor. + */ + virtual ~ObstacleAction(); + + /*! + * @brief Upon entering the state, this is called -- it is the main work + * of the action. + * + * @param agent The agent to act on. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + friend class ObstacleActFactory; + protected: + + /*! + * @brief The work to do upon state exit. + * + * @param agent The agent to act on. + */ + virtual void leaveAction( Agents::BaseAgent * agent ); + + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original obstacle set value. + * @returns The new value. + */ + virtual size_t newValue( size_t value ) = 0; + + /*! + * @brief The set operand to apply to the agents obstacle set. + */ + size_t _setOperand; + + /*! + * @brief A mapping from agent id to the agent's obstacle set + * value before the action was applied. + */ + std::map< size_t, size_t > _originalMap; + + /*! + * @brief Lock for guaranteeing thread-safety. + */ + SimpleLock _lock; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ObstacleAction. + * + * This is still an abstract class because it doesn't define the + * name or description. Nor does it define instance. + */ + class MENGE_API ObstacleActFactory : public ActionFactory { + public: + /*! + * @brief Constructor. + */ + ObstacleActFactory(); + + protected: + /*! + * @brief Given a pointer to an Action instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Action's type. + * (i.e. ActionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ActionFactory introduce *new* Action parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param action A pointer to the action whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "operand" size_t attribute. + */ + size_t _operandID; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies the agent's obstacle set by REMOVING the given obstacle + * set value. + */ + class MENGE_API RemoveObstacleSetAction : public ObstacleAction { + public: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original obstacle set value. + * @returns The new value. + */ + virtual size_t newValue( size_t value ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the RemoveObstacleSetAction. + */ + class MENGE_API RemoveObstacleActFactory : public ObstacleActFactory { + public: + /*! + * @brief Constructor. + */ + RemoveObstacleActFactory():ObstacleActFactory() {} + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "remove_obstacle"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Removes the specified obstacle set from the agents consideration"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new RemoveObstacleSetAction(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies the agent's obstacle set by ADDING the given obstacle + * set value. + */ + class MENGE_API AddObstacleSetAction : public ObstacleAction { + public: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original obstacle set value. + * @returns The new value. + */ + virtual size_t newValue( size_t value ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ObstacleActFactory. + */ + class MENGE_API AddObstacleyActFactory : public ObstacleActFactory { + public: + /*! + * @brief Constructor. + */ + AddObstacleyActFactory():ObstacleActFactory() {} + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "add_obstacle"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Adds the specified obstacle set from the agents consideration"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new AddObstacleSetAction(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Modifies the agent's obstacle set by SETTING the given obstacle + * set value (i.e. overriding the old value with the new). + */ + class MENGE_API SetObstacleSetAction : public ObstacleAction { + public: + /*! + * @brief Computes the new property value given the original property value. + * + * @param value The original obstacle set value. + * @returns The new value. + */ + virtual size_t newValue( size_t value ); + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the SetObstacleSetAction. + */ + class MENGE_API SetObstacleActFactory : public ObstacleActFactory { + public: + /*! + * @brief Constructor. + */ + SetObstacleActFactory():ObstacleActFactory() {} + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "set_obstacle"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Sets the specified obstacle set from the agents consideration"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new SetObstacleSetAction(); } + }; + + } // namespace BFSM + +} // namespace Menge +#endif // __OBSTACLE_ACTION_H__ diff --git a/src/Menge/MengeCore/BFSM/Actions/PropertyAction.h b/src/Menge/MengeCore/BFSM/Actions/PropertyAction.h new file mode 100644 index 00000000..7e00368d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/PropertyAction.h @@ -0,0 +1,317 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PropertyAction.h + * @brief Defines a set of BFSM actions that change agent + * parameters. + */ + +#ifndef __PROPERTY_ACTION_H__ +#define __PROPERTY_ACTION_H__ + +#include "CoreConfig.h" +#include "Actions/Action.h" +#include "Actions/ActionFactory.h" +#include "fsmCommon.h" +#include "AgentPropertyManipulator.h" + +namespace Menge { + + // forward declaration + + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + + //////////////////////////////////////////////////////////////////// + + /*! + * @brief The base class for modifying agent properties. + * + * This is an abstract class and must be sub-classed. To create different + * types of property actions, simply specialize this templated class with + * a different type of AgentPropertyManipulator. + */ + template + class MENGE_API PropertyAction : public Action { + public: + /*! + * @brief Constructor + */ + PropertyAction():Action(), _manip() {} + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~PropertyAction(){} + + public: + /*! + * @brief Upon entering the state, this is called -- it is the main work + * of the action. + * + * @param agent The agent to act on. + */ + virtual void onEnter( Agents::BaseAgent * agent ) { _manip.manipulate( agent ); } + + /*! + * @brief Returns a pointer to the manipulator. + */ + Manipulator * getManipulator() { return &_manip; } + + protected: + + /*! + * @brief The work to do upon state exit. + * + * @param agent The agent to act on. + */ + virtual void leaveAction( Agents::BaseAgent * agent ) { _manip.restore( agent ); } + + /*! + * @brief The manipulator responsible for changing agent properties. + */ + Manipulator _manip; + + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the PropertyAction. + * + * This is still an abstract class because it doesn't define the + * name or description. Nor does it define instance. + */ + template + class MENGE_API PropertyActFactory : public ActionFactory { + public: + /*! + * @brief Constructor. + */ + PropertyActFactory() { + _propertyID = _attrSet.addStringAttribute( "property", true /*required*/ ); + _generatorID = _attrSet.addFloatDistAttribute( "", true /*required*/, 0.f, 1.f ); + } + + protected: + /*! + * @brief Given a pointer to an Action instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Action's type. + * (i.e. ActionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ActionFactory introduce *new* Action parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param action A pointer to the action whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const { + PropertyAction< Manipulator > * pAction = dynamic_cast< PropertyAction< Manipulator > * >( action ); + assert( pAction != 0x0 && "Trying to set property action properties on an incompatible object" ); + + if ( ! ActionFactory::setFromXML( action, node, behaveFldr ) ) return false; + Menge::AgentPropertyManipulator * manip = pAction->getManipulator(); + + PropertyOperand prop = Menge::parsePropertyName( _attrSet.getString( _propertyID ) ); + manip->setProperty( prop ); + if ( prop == NO_PROPERTY ) { + logger << Logger::ERR_MSG << "The property action defined on line " << node->Row() << " specified an invalid value for the \"property\" attribute"; + return false; + } + manip->setGenerator( _attrSet.getFloatGenerator( _generatorID ) ); + + return true; + } + + /*! + * @brief The identifier for the "property" string attribute. + */ + size_t _propertyID; + + /*! + * @brief The identifier for the float distribution attribute. + */ + size_t _generatorID; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the SetPropertyAction. + */ + class MENGE_API SetPropertyActFactory : public PropertyActFactory< Menge::SetPropertyManipulator > { + public: + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "set_property"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Causes the specified property to be *replaced* by the user-defined value"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new PropertyAction< Menge::SetPropertyManipulator >(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the OffsetPropertyAction. + */ + class MENGE_API OffsetPropertyActFactory : public PropertyActFactory< Menge::OffsetPropertyManipulator > { + public: + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "offset_property"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Adds the user-defined value into the agent's specified property"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new PropertyAction< Menge::OffsetPropertyManipulator >(); } + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ScalePropertyAction. + */ + class MENGE_API ScalePropertyActFactory : public PropertyActFactory< Menge::ScalePropertyManipulator > { + public: + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "scale_property"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Scales the user-defined value into the agent's specified property"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const { return new PropertyAction< Menge::ScalePropertyManipulator >(); } + }; + + } // namespace BFSM + +} // namespace Menge + +#endif // __PROPERTY_ACTION_H__ diff --git a/src/Menge/MengeCore/BFSM/Actions/TeleportAction.cpp b/src/Menge/MengeCore/BFSM/Actions/TeleportAction.cpp new file mode 100644 index 00000000..4d6fbfc2 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/TeleportAction.cpp @@ -0,0 +1,94 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Actions/TeleportAction.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of TeleportAction + ///////////////////////////////////////////////////////////////////// + + TeleportAction::TeleportAction():Action(), _goals(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + TeleportAction::~TeleportAction() { + if ( _goals ) delete _goals; + } + + ///////////////////////////////////////////////////////////////////// + + void TeleportAction::onEnter( Agents::BaseAgent * agent ) { + assert( _goals != 0x0 && "Trying to use an improperly initialized TeleportAction - no goal generator defined" ); + agent->_pos.set( _goals->getValueConcurrent() ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of TeleportActFactory + ///////////////////////////////////////////////////////////////////// + + TeleportActFactory::TeleportActFactory():ActionFactory() { + _2DGoalID = _attrSet.addVec2DDistAttribute( true/*required*/, Vector2(0.f, 0.f)/*default*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + Action * TeleportActFactory::instance() const { + return new TeleportAction(); + } + + ///////////////////////////////////////////////////////////////////// + + bool TeleportActFactory::setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const { + TeleportAction * tpAction = dynamic_cast< TeleportAction * >( action ); + assert( action != 0x0 && "Trying to set teleport action properties on an incompatible object" ); + + if ( ! ActionFactory::setFromXML( action, node, behaveFldr ) ) return false; + // Override undoing the teleport regardless of what was set in the XML + tpAction->_undoOnExit = false; + tpAction->_goals = _attrSet.getVec2DGenerator( _2DGoalID ); + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Actions/TeleportAction.h b/src/Menge/MengeCore/BFSM/Actions/TeleportAction.h new file mode 100644 index 00000000..fcf02026 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Actions/TeleportAction.h @@ -0,0 +1,181 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TeleportAction.h + * @brief Defines a BFSM action that causes agents to + * teleport to a new location. + */ + +#ifndef __TELEPORT_ACTION_H__ +#define __TELEPORT_ACTION_H__ + +#include "CoreConfig.h" +#include "Actions/Action.h" +#include "Actions/ActionFactory.h" +#include "fsmCommon.h" + +namespace Menge { + + // forward declaration + + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + // forward declaration + class TeleportActFactory; + + /*! + * @brief Causes the agents to teleport to a new location. + * + * This action does *not* undo the teleport on leaving the state. It is + * hard-wired this way. + */ + class MENGE_API TeleportAction : public Action { + public: + /*! + * @brief Constructor + * + */ + TeleportAction(); + + /*! + * @brief Virtual destructor. + */ + virtual ~TeleportAction(); + + /*! + * @brief Upon entering the state, this is called -- it is the main work + * of the action. + * + * @param agent The agent to act on. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + friend class TeleportActFactory; + protected: + + /*! + * @brief The work to do upon state exit. + * + * @param agent The agent to act on. + */ + virtual void leaveAction( Agents::BaseAgent * agent ) {} + + /*! + * @brief The generator for computing teleport destination locations. + */ + Vec2DGenerator * _goals; + }; + + /*! + * @brief Factory for the TeleportAction. + */ + class MENGE_API TeleportActFactory : public ActionFactory { + public: + /*! + * @brief Constructor. + */ + TeleportActFactory(); + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "teleport"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Causes the agent to teleport to a user-specified location based on a 2D generator"; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + Action * instance() const; + + /*! + * @brief Given a pointer to an Action instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Action's type. + * (i.e. ActionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ActionFactory introduce *new* Action parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param action A pointer to the action whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Action * action, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "exit_reset" boolean attribute. + */ + size_t _2DGoalID; + }; + + } // namespace BFSM + +} // +#endif // __TELEPORT_ACTION_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/FSM.cpp b/src/Menge/MengeCore/BFSM/FSM.cpp new file mode 100644 index 00000000..7bcf69d5 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSM.cpp @@ -0,0 +1,317 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "FSM.h" + +#include "State.h" +#include "Transitions/Transition.h" +#include "Tasks/Task.h" +#include "Core.h" +#include "FsmContext.h" +#include "StateContext.h" +#include "GoalSet.h" +#include "PrefVelocity.h" +#include "Events/EventSystem.h" + +#include "BaseAgent.h" +#include "SimulatorInterface.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FSM + ///////////////////////////////////////////////////////////////////// + + FSM::FSM( Agents::SimulatorInterface * sim ):_sim(sim), _agtCount(0), _currNode(0x0) { + setAgentCount( sim->getNumAgents() ); + } + + ///////////////////////////////////////////////////////////////////// + + FSM::~FSM() { + if ( _currNode ) { + delete [] _currNode; + } + // TODO: Why doesn't this delete the States and transitions? + std::map< size_t, GoalSet * >::iterator gsItr = _goalSets.begin(); + for ( ; gsItr != _goalSets.end(); ++gsItr ) { + delete gsItr->second; + } + for ( size_t i = 0; i < _tasks.size(); ++i ) { + _tasks[ i ]->destroy(); + } + _tasks.clear(); + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::collectTasks() { + const size_t STATE_COUNT = _nodes.size(); + for ( size_t i = 0; i < STATE_COUNT; ++i ) { + _nodes[ i ]->getTasks( this ); + } + + //now collect the velocity modifiers tasks + std::vector< VelModifier * >::iterator vItr = _velModifiers.begin(); + for ( ; vItr != _velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer + addTask((*vItr)->getTask()); + } + + //iterate over agents + + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::addTask( Task * task ) { + if ( task ) { + for ( size_t i = 0; i < _tasks.size(); ++i ) { + if ( task->isEquivalent( _tasks[i] ) ) { + task->destroy(); + return; + } + } + _tasks.push_back( task ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::setAgentCount( size_t count ) { + if ( _currNode ) { + delete [] _currNode; + _currNode = 0x0; + } + _agtCount = count; + _currNode = new State * [ count ]; + memset( _currNode, 0x0, count * sizeof( State * ) ); + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::advance( Agents::BaseAgent * agent ) { + const size_t ID = agent->_id; + // Evaluate the current state's transitions + State * newNode = _currNode[ ID ]->testTransitions( agent ); + if ( newNode ) { + _currNode[ ID ] = newNode; + } + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::computePrefVelocity( Agents::BaseAgent * agent ) { + const size_t ID = agent->_id; + // Evalute the new state's velocity + + //generate a preferred velocity for passing around + Agents::PrefVelocity newVel; + + _currNode[ ID ]->getPrefVelocity( agent, newVel); + + //TODO: My velocity modifiers here + + std::vector< VelModifier * >::iterator vItr = _velModifiers.begin(); + for ( ; vItr != _velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer + (*vItr)->adaptPrefVelocity(agent, newVel); + } + + + //agent will now have a set preferred velocity method + agent->setPreferredVelocity(newVel); + } + + ///////////////////////////////////////////////////////////////////// + + State * FSM::getNode( const std::string & name ) { + const size_t STATE_COUNT = _nodes.size(); + for ( size_t i = 0; i < STATE_COUNT; ++i ) { + if ( _nodes[i]->getName() == name ) { + return _nodes[i]; + } + } + return 0x0; + } + + ///////////////////////////////////////////////////////////////////// + + size_t FSM::addNode( State *node ) { + if ( _currNode[0] == 0x0 ) { + for ( size_t i = 0; i < _agtCount; ++i ) { + _currNode[i] = node; + } + } + _nodes.push_back( node ); + return _nodes.size() - 1; + } + + ///////////////////////////////////////////////////////////////////// + + bool FSM::addTransition( size_t fromNode, Transition * t ) { + if ( fromNode >= _nodes.size() ) return false; + State * from = _nodes[ fromNode ]; + from->addTransition( t ); + return true; + } + + ///////////////////////////////////////////////////////////////////// + + bool FSM::addGoal( size_t goalSet, size_t goalID, Goal * goal ) { + if ( _goalSets.find( goalSet ) == _goalSets.end() ) { + _goalSets[ goalSet ] = new GoalSet(); + } + return _goalSets[ goalSet ]->addGoal( goalID, goal ); + } + + ///////////////////////////////////////////////////////////////////// + + const Goal * FSM::getGoal( size_t goalSet, size_t goalID ) { + if ( _goalSets.find( goalSet ) == _goalSets.end() ) { + return 0x0; + } + return _goalSets[ goalSet ]->getGoalByID( goalID ); + } + + ///////////////////////////////////////////////////////////////////// + + const GoalSet * FSM::getGoalSet( size_t goalSetID ) { + if ( _goalSets.find( goalSetID ) == _goalSets.end() ) { + return 0x0; + } + return _goalSets[ goalSetID ]; + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::setCurrentState( Agents::BaseAgent * agent, size_t currNode ) { + assert( currNode < _nodes.size() && "Set invalid state as current state" ); + _currNode[ agent->_id ] = _nodes[ currNode ]; + } + + ///////////////////////////////////////////////////////////////////// + + State * FSM::getCurrentState( const Agents::BaseAgent * agt ) const { + return _currNode[ agt->_id ]; + } + + ///////////////////////////////////////////////////////////////////// + + size_t FSM::getAgentStateID( const Agents::BaseAgent * agent ) const { + return _currNode[ agent->_id ]->getID(); + } + + ///////////////////////////////////////////////////////////////////// + + size_t FSM::getAgentStateID( size_t agentID ) const { + return _currNode[ agentID ]->getID(); + } + + ///////////////////////////////////////////////////////////////////// + + bool FSM::allFinal() const { + // NOTE: This assumes that there are no holes in this memory + for ( size_t a = 0; a < _agtCount; ++a ) { + if ( !_currNode[ a ]->getFinal() ) return false; + } + return true; + } + + ///////////////////////////////////////////////////////////////////// + + bool FSM::doStep() { + // NOTE: This is a cast from size_t to int to be compatible with older implementations + // of openmp which require signed integers as loop variables + SIM_TIME = this->_sim->getGlobalTime(); + EVENT_SYSTEM->evaluateEvents(); + int agtCount = (int)this->_sim->getNumAgents(); + size_t exceptionCount = 0; + #pragma omp parallel for reduction(+:exceptionCount) + for ( int a = 0; a < agtCount; ++a ) { + Agents::BaseAgent * agt = this->_sim->getAgent( a ); + try { + advance( agt ); + this->computePrefVelocity( agt ); + } catch ( StateException & e ) { + logger << Logger::ERR_MSG << e.what() << "\n"; + ++exceptionCount; + } + } + if ( exceptionCount > 0 ) { + throw FSMFatalException(); + } + return this->allFinal(); + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::doTasks() { + for ( size_t i = 0; i < this->_tasks.size(); ++i ) { + try { + this->_tasks[i]->doWork( this ); + } catch ( TaskFatalException ) { + logger << Logger::ERR_MSG << "Fatal error in FSM task: " << _tasks[i]->toString() << "\n"; + throw FSMFatalException(); + } catch ( TaskException ) { + logger << Logger::ERR_MSG << "Error in FSM task: " << _tasks[i]->toString() << "\n"; + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void FSM::finalize() { + EVENT_SYSTEM->finalize(); + doTasks(); + } + + ///////////////////////////////////////////////////////////////////// + + FsmContext * FSM::getContext() { + FsmContext * ctx = new FsmContext( this ); + // TODO: Populate the context + for ( size_t i = 0; i < _nodes.size(); ++i ) { + StateContext * sCtx = new StateContext( _nodes[ i ] ); + ctx->addStateContext( _nodes[i]->getID(), sCtx ); + } + + return ctx; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/FSM.h b/src/Menge/MengeCore/BFSM/FSM.h new file mode 100644 index 00000000..fe5e0d75 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSM.h @@ -0,0 +1,405 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FSM.h + * @brief The definition of the behavior finite state machine. + */ + +#ifndef __FSM_H__ +#define __FSM_H__ + +// Finite-state machine used to compute preferred velocity +// according to varying conditions + +#include "fsmCommon.h" +#include "FSMDescrip.h" +#include "MengeException.h" + +#include +#include +#include +#ifndef _MSC_VER +#include +#endif + + +namespace Menge { + // forward declaration + namespace Agents { + class SimulatorInterface; + class BaseAgent; + } + + namespace BFSM { + + // Forward declaration + class FsmContext; + class State; + class Transition; + class Goal; + class GoalSet; + class Task; + class FSMDescrip; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Generic base class for FSM exceptions. + */ + class FSMException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + FSMException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + FSMException( const std::string & s ): MengeException(s) {} + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Exception thrown when the FSM has an error which cannot be + * recovered from. + */ + class FSMFatalException : public FSMException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + FSMFatalException() : MengeException(), FSMException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + FSMFatalException( const std::string & s ): MengeException(s), FSMException(), MengeFatalException() {} + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Templated class for the behavior finite state machine. + */ + class FSM { + public: + /*! + * @brief Constructor. + * + * @param sim The simulator to operate on. + */ + FSM( Agents::SimulatorInterface * sim ); + + /*! + * @brief Destructor + */ + ~FSM(); + + /*! + * @brief Collects all tasks from the FSM elements. + */ + void collectTasks(); + + /*! + * @brief Adds a task to the set. + * + * Elements can blindly add tasks to the finite state machine (including adding + * a null pointer. If the pointer is null, no work is done. If the pointer is + * a duplicate of a previous task, it will not be repeatedly added. + * + * The FSM takes possession of the task and is responsible for cleaning the memory. + * + * @param task A pointer to a task to add. + */ + void addTask( Task * task ); + + /*! + * @brief Initializes the memory required for the number of agents + * included in the FSm. + * + * @param count The number of agents. + */ + void setAgentCount( size_t count ); + + /*! + * @brief Advances the FSM based on the current state for the given + * agent. + * + * @param agent The agent to advance the FSM for. + */ + void advance( Agents::BaseAgent * agent ); + + /*! + * @brief Computes the preferred velocity for the given agent + * based on the FSM's record of which state the agent is in. + */ + void computePrefVelocity( Agents::BaseAgent * agent ); + + /*! + * @brief Get the pointer for the node with the given identifier. + * + * @param id The state identifier. Id is not validated. + * @returns A pointer to the state with the given identifier. + */ + State * getNode( size_t id ) { return _nodes[id]; } + + /*! + * @brief Returns the state with the given name. + * + * @param name The name of the desired state. + * @returns A pointer to the desired state (if it is found), + * otherwise, returns null. + */ + State * getNode( const std::string & name ); + + /*! + * @brief Reports the number of states in the FSM. + * + * @returns The number of states in the fsm. + */ + size_t getNodeCount() const { return _nodes.size(); } + + /*! + * @brief Adds a state to the BFSM. + * + * @param node The state to add. + * @returns A unique identifier for the newly added state. + */ + size_t addNode( State * node ); + + /*! + * @brief Adds the given transition to the FSM. + * + * The transition already contains a pointer to the destination state + * (see Transition). + * + * @param fromNode The global identifier from the origin state. + * @param t The transition to add. + * @returns True if the transition is successfully added, false otherwise. + */ + bool addTransition( size_t fromNode, Transition * t ); + + /*! + * @brief Adds a goal to the indicated goal set. + * + * @param goalSet The id of the goal set which receives the goal. + * @param goalID The id of the goal in the goal set. + * @param goal The goal to add. + * @returns A boolean reporting success (true) or failure (false) + */ + bool addGoal( size_t goalSet, size_t goalID, Goal * goal ); + + /*! + * @brief Retrieves the given goal from the given goal set. + * + * @param goalSet The identifier of the goal set. + * @param goalID The identifier of the goal. + * @returns A pointer to the corresponding goal. If no such goal exists + * NULL is returned. + */ + const Goal * getGoal( size_t goalSet, size_t goalID ); + + /*! + * @brief Retrives the given goal set. + * + * @param goalSetID The identifier of the goal set. + * @returns A pointer to the corresponding goal set. If no such goal set + * exists, NULL is returned. + */ + const GoalSet * getGoalSet( size_t goalSetID ); + + /*! + * @brief Update the fsm state by one time step + * + * @returns A boolean reporting if all agents are in a final state (true) + * or not (false). + */ + bool doStep(); + + /*! + * @brief Sets the current state for the given agent. + * + * @param agt The agent whose BFSM state gets set. + * @param currNode The unique identifier of the desired state + * (returned by FSM::addNode). + */ + void setCurrentState( Agents::BaseAgent * agt, size_t currNode ); + + /*! + * @brief Gets a pointer to the state the agent is currently in. + * + * @param agt The agent. + * @returns A pointer to the agent's current state. + */ + State * getCurrentState( const Agents::BaseAgent * agt ) const; + + /*! + * @brief Reports the state the given agent is currently in. + * + * @param agent A pointer to the agent whose state id is returned. + * @returns The id of the state the given agent is in. + */ + size_t getAgentStateID( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Reports the state the given agent is currently in. + * + * @param agentID The unique id of the agent whose state id is returned. + * @returns The id of the state the given agent is in. + */ + size_t getAgentStateID( size_t agentID ) const; + + /*! + * @brief Reports if all agents are in final states (i.e. the simulation is done.) + * + * @returns True if all agents are in a final state, false otherwise. + */ + bool allFinal() const; + + /*! + * @brief Retrieve the simulator + */ + inline const Agents::SimulatorInterface * getSimulator() const { return _sim; } + + /*! + * @brief Performs the work in the FSM's tasks. + */ + void doTasks(); + + /*! + * @brief Returns the number of registered tasks. + */ + size_t getTaskCount() const { return _tasks.size(); } + + /*! + * @brief Finalize the FSM + */ + void finalize(); + + /*! + * @brief Returns the BFSM Context for this FSM + * + * A new FsmContext will be constructed upon each call to + * this function. It is the responsibility of the caller to + * make sure it gets deleted. + * + * @returns A pointer to a valid fsm context. + */ + FsmContext * getContext(); + + /*! + * @brief Returns the goal sets defined in the simulator. + * + * @returns A reference to the goal set map. + */ + std::map< size_t, GoalSet * > & getGoalSets() { return _goalSets; } + + friend FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ); + + /*! + * @brief Add an velocity modifier to the FSM + * + * @param v The modifier to add + */ + void addVelModifier( VelModifier * v ) { _velModifiers.push_back( v ); } + + protected: + /*! + * @brief The simulator on which the FSM acts. + */ + Agents::SimulatorInterface * _sim; + + /*! + * @brief Number of agents attached to the state machine + * + * This should be the same as the number of agents in the simulator. + */ + size_t _agtCount; + + /*! + * @brief The active state for each agent in the system. + */ + State ** _currNode; + + /*! + * @brief The states in the BFSM. + */ + std::vector< State * > _nodes; + + /*! + * @brief The set of tasks to perform at each time step + */ + std::vector< Task * > _tasks; + + /*! + * @brief Mapping from goal set identifier to GoalSet. + */ + std::map< size_t, GoalSet * > _goalSets; + + /*! + * @brief A list of velocity modifiers to be applied to all states in the simulator + */ + std::vector< VelModifier * > _velModifiers; + + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Templated function which builds the behavior fsm from the + * behavior configuration given. + * + * @param fsmDescrip The Behavior configuration. + * @param sim The simulator which uses the BFSM. + * @param VERBOSE The optional argument which causes the construction + * process to report actions as it goes. + * @returns A pointer to the resultant FSM. If there is an error in + * construction, NULL is returned. + */ + FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE=false ); + + } // namespace BFSM +} // namespace Menge +#endif // __FSM_H__ diff --git a/src/Menge/MengeCore/BFSM/FSMDescrip.cpp b/src/Menge/MengeCore/BFSM/FSMDescrip.cpp new file mode 100644 index 00000000..4235d9fa --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSMDescrip.cpp @@ -0,0 +1,245 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "FSMDescrip.h" +#include "Logger.h" +#include "GoalSet.h" +#include "Goals/Goal.h" +#include "Tasks/Task.h" +#include "State.h" +#include "Transitions/Transition.h" +#include "Transitions/Target.h" +#include "Transitions/TargetDatabase.h" +#include "Transitions/ConditionDatabase.h" +#include "VelocityModifiers/VelModifier.h" +#include "VelocityModifiers/VelModifierDatabase.h" +#include "StateDescrip.h" +#include "Events/EventSystem.h" +#include "Events/Event.h" +#include "Core.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FSMDescrip + ///////////////////////////////////////////////////////////////////// + + FSMDescrip::FSMDescrip() { + } + + ///////////////////////////////////////////////////////////////////// + + FSMDescrip::~FSMDescrip() { + std::list< StateDescrip * >::const_iterator sItr = _states.begin(); + for ( ; sItr != _states.end(); ++sItr ) { + delete (*sItr ); + } + std::map< std::string, std::list< Transition * > >::iterator stItr = _transitions.begin(); + for ( ; stItr != _transitions.end(); ++stItr ) { + std::list< Transition * > & tList = stItr->second; + std::list< Transition * >::iterator tItr = tList.begin(); + for ( ; tItr != tList.end(); ++tItr ) { + delete ( *tItr ); + } + } + + std::map< size_t, GoalSet * >::iterator gItr = _goalSets.begin(); + for ( ; gItr != _goalSets.end(); ++gItr ) { + delete gItr->second; + } + + std::list< Task * >::iterator tItr = _tasks.begin(); + for ( ; tItr != _tasks.end(); ++tItr ) { + (*tItr)->destroy(); + } + } + + ///////////////////////////////////////////////////////////////////// + + State * FSMDescrip::addState( StateDescrip * sData ) { + if ( _stateNameMap.find( sData->_name ) != _stateNameMap.end() ) { + logger << Logger::ERR_MSG << "Found multiple states with the same name: \"" << sData->_name << "\"."; + return 0x0; + } + State * node = new State( sData->_name ); + node->setFinal( sData->_isFinal ); + _stateNameMap[ sData->_name ] = node; + return node; + } + + ///////////////////////////////////////////////////////////////////// + + bool FSMDescrip::loadFromXML( const std::string & xmlName, bool verbose ) { + logger << Logger::INFO_MSG << "Loading behavior from xml: " << xmlName; + TiXmlDocument xml( xmlName ); + bool loadOkay = xml.LoadFile(); + + if ( !loadOkay ) { + logger << Logger::ERR_MSG << "Could not load behavior configuration xml (" << xmlName << ") due to xml syntax errors.\n"; + logger << "\t" << xml.ErrorDesc(); + return false; + } + + TiXmlElement * popNode = xml.RootElement(); + if ( ! popNode ) { + logger << Logger::ERR_MSG << "Root element does not exist."; + return false; + } + if ( popNode->ValueStr() != "BFSM" ) { + logger << Logger::ERR_MSG << "Root element value should be \"BFSM\"."; + return false; + } + + std::string absPath; + os::path::absPath( xmlName, absPath ); + std::string junk; + os::path::split( absPath, _behaviorFldr, junk ); + logger << Logger::INFO_MSG << "Behavior root: " << _behaviorFldr; + + TiXmlElement* child; + for ( child = popNode->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == "GoalSet" ) { + int i; + if ( !child->Attribute( "id", &i ) ) { + logger << Logger::ERR_MSG << "GoalSet requires an \"id\" property."; + return false; + } + size_t setID = static_cast< size_t >( i ); + // confirm that the id doesn't already exist + if ( _goalSets.find( setID ) != _goalSets.end() ) { + logger << Logger::WARN_MSG << "Found multiple GoalSets with the same id: " << setID << ".\n\tGoal definitions will be merged!"; + } else { + _goalSets[ setID ] = new GoalSet(); + } + TiXmlElement * goalNode; + for ( goalNode = child->FirstChildElement(); goalNode; goalNode = goalNode->NextSiblingElement() ) { + if ( goalNode->ValueStr() == "Goal" ) { + Goal * goal = parseGoal( goalNode, _behaviorFldr ); + if ( goal == 0x0 ) { + logger << Logger::ERR_MSG << "Error parsing a goal description."; + return false; + } + // Make sure that this goal doesn't duplicate previous goal ids + if ( ! _goalSets[ setID ]->addGoal( goal->getID(), goal ) ) { + logger << Logger::ERR_MSG << "GoalSet " << setID << " has two goals with the identifier: " << goal->getID() << " (second appears on line " << goalNode->Row() << ")."; + return false; + } + } else { + logger << Logger::WARN_MSG << "Found a child tag of the GoalSet that is not a \"Goal\" tag on line " << goalNode->Row() << ". It will be ignored."; + } + } + + } else if ( child->ValueStr() == "State" ) { + if ( ! parseState( child, _behaviorFldr, _states ) ) { + + return false; + } + } else if ( child->ValueStr() == "Transition" ) { + std::string from; + Transition * trans = parseTransition( child, _behaviorFldr, from ); + if ( trans == 0x0 ) { + return false; + } + + addTransition( from, trans ); + } else if ( child->ValueStr() == "VelModifier" ) { + VelModifier *vel = parseVelModifier( child, _behaviorFldr); + if ( vel == 0x0 ) { + return false; + } else { + _velModifiers.push_back(vel); + } + } else if ( child->ValueStr() == "Task" ) { + + Task * task = parseTask( child, _behaviorFldr ); + if ( task == 0x0 ) { + logger << Logger::WARN_MSG << "User-specified Task on line " << child->Row() << " couldn't be instantiated. It is being ignored."; + } else { + _tasks.push_back( task ); + } + } else if ( child->ValueStr() == "EventSystem" ) { + if ( ! EVENT_SYSTEM->parseEvents( child, _behaviorFldr ) ) { + return false; + } + } else { + logger << Logger::ERR_MSG << "Unrecognized tag as child of : <" << child->ValueStr() << ">."; + return false; + } + } + + return true; + } + + ///////////////////////////////////////////////////////////////////// + + void FSMDescrip::addTransition( const std::string & name, Transition * trans ) { + std::string tmpName( name ); + size_t n = tmpName.find_first_of( ',' ); + while ( n != std::string::npos ) { + std::string sName = tmpName.substr( 0, n ); + _transitions[ sName ].push_back( trans->copy() ); + tmpName = tmpName.substr( n + 1 ); + n = tmpName.find_first_of( ',' ); + } + + _transitions[ tmpName ].push_back( trans ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const FSMDescrip & fsmDescrip ) { + out << "BFSM Configuration:"; + out << "\n\tStates:"; + std::list< StateDescrip * >::const_iterator sItr = fsmDescrip._states.begin(); + for ( ; sItr != fsmDescrip._states.end(); ++sItr ) { + out << "\n" << (*(*sItr) ); + } + out << "\n\tTransitions:"; + std::map< std::string, std::list< Transition * > >::const_iterator tItr = fsmDescrip._transitions.begin(); + for ( ; tItr != fsmDescrip._transitions.end(); ++tItr ) { + out << "\nNo Transition output supported."; + } + return out; + } + + ///////////////////////////////////////////////////////////////////// + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/FSMDescrip.h b/src/Menge/MengeCore/BFSM/FSMDescrip.h new file mode 100644 index 00000000..c41403ed --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSMDescrip.h @@ -0,0 +1,193 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FSMDescrip.h + * @brief The definition of behavior finite state machines. + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#include +#include +#include + +#include "fsmCommon.h" + + +// Configuration description classes +#include "StateDescrip.h" +#include "resources/ResourceManager.h" +#include "resources/VectorField.h" + +#include "Logger.h" +#include "os.h" +#include "tinyxml.h" + + +namespace Menge { + + // forward declarations + namespace Agents { + class SimulatorInterface; + } + + namespace BFSM { + // Forward declaration + class FSM; + class GoalSet; + class Task; + class State; + class Transition; + class StateDescrip; + class VelModifier; + + /*! + * @brief The full description of the behavioral finite state machine + */ + class FSMDescrip { + public: + /*! + * @brief Default constructor. + */ + FSMDescrip(); + + /*! + * @brief Destructor. + */ + ~FSMDescrip(); + + /*! + * @brief Instantiates a state based on the description. + * + * This is a behavior operation, because the behavior is responsible for: + * - tracking its states by name, + * - confirming no State name conflicts, and + * - connecting states with transitions. + * + * @param sData The description of the state to create. + * @returns A pointer to the created state. If there are two states with the same name + * *in this behavior*, NULL is returned. + */ + State * addState( StateDescrip * sData ); + + /*! + * @brief Initializes the configuration from an xml file. + * + * @param xmlName The path to the xml file containing the behavior + * specification. + * @param verbose Dictates whether the parsing is verbose. + * @returns True if parsing was successfful, false otherwise. + */ + bool loadFromXML( const std::string & xmlName, bool verbose ); + + /*! + * @brief Creates an FSM instance from the config file. + * + * @param fsmDescrip The behavior configuration description. + * @param sim An instance of the simulator. + * @param VERBOSE Dictates whether the construction process is verbose (true) + * or not (false). + */ + friend FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ); + + /*! + * @brief Friend operator for printing the behavior configuration to an output stream. + * + * @param out The logger. + * @param fsmDescrip A behavior configuration to write to the stream. + * @returns The provided output stream. + */ + friend Logger & operator<<( Logger & out, const FSMDescrip & fsmDescrip ); + + protected: + + /*! + * @brief Adds the transition(s) associated with the given name. + * + * @param name The name of the state from which the transition + * originates. Alternatively, a comma-separated list. + * @param trans The transition to add. The FSMDescrip takes ownership + * of the transition. + */ + void addTransition( const std::string & name, Transition * trans ); + + /*! + * @brief List of state descriptions. + */ + std::list< StateDescrip * > _states; + + /*! + * @brief List of transitions. + */ + std::map< std::string, std::list< Transition * > > _transitions; + + /*! + * @brief Map of state names to states. + */ + std::map< std::string, State * > _stateNameMap; + + /*! + * @brief A map from agent class id to a behavior description instance. + */ + std::list< Task * > _tasks; + + /*! + * @brief A mapping of goal sets to goals. + * The goal sets are represented by their id. The goals for each goal + * set are stored in a map, mapping the goal's local id to a descriptor for + * that goal. This is to facilitate set additions. + */ + std::map< size_t, GoalSet * > _goalSets; + + /*! + * @brief A list of velocity modifiers to be applied to all states in the simulator + */ + std::vector< VelModifier * > _velModifiers; + + /*! + * @brief The folder in which the behavior specification file appears + */ + std::string _behaviorFldr; + + }; + } // namespace BFSM +} // namespace Menge + +#endif // __CONFIG_H__ diff --git a/src/Menge/MengeCore/BFSM/FSMEnumeration.cpp b/src/Menge/MengeCore/BFSM/FSMEnumeration.cpp new file mode 100644 index 00000000..4ce83361 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSMEnumeration.cpp @@ -0,0 +1,73 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "FSMEnumeration.h" + +namespace Menge { + + Logger & operator<<( Logger & out, const BFSM::PropertyOperand op ) { + switch ( op ) { + case BFSM::NO_PROPERTY: + out << "invalid property"; + break; + case BFSM::MAX_SPEED: + out << "maximum speed"; + break; + case BFSM::MAX_ACCEL: + out << "maximum acceleration"; + break; + case BFSM::PREF_SPEED: + out << "preferred speed"; + break; + case BFSM::MAX_ANGLE_VEL: + out << "maximum angular velocity"; + break; + case BFSM::NEIGHBOR_DIST: + out << "neighbor distance"; + break; + case BFSM::PRIORITY: + out << "priority"; + break; + case BFSM::RADIUS: + out << "radius"; + break; + } + return out; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/FSMEnumeration.h b/src/Menge/MengeCore/BFSM/FSMEnumeration.h new file mode 100644 index 00000000..06151127 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FSMEnumeration.h @@ -0,0 +1,87 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FSMEnumeration.h + * @brief Enumerated types for the State class. + */ + +#ifndef __STATE_ENUM_H__ +#define __STATE_ENUM_H__ + +#include "Logger.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The set of properties on which a PropertyAction can be used. + */ + enum PropertyOperand { + NO_PROPERTY, ///< The "NULL" property - indicating no valid property. + MAX_SPEED, ///< The agent's maximum speed. + MAX_ACCEL, ///< The agent's maximum, isotropic acceleration. + PREF_SPEED, ///< The agent's preferred speed. + MAX_ANGLE_VEL, ///< The agent's maximum angular velocity + NEIGHBOR_DIST, ///< The agent's neighbor distance + PRIORITY, ///< The agent's priority + RADIUS ///< The agent's radius + }; + + /*! + * @brief An enumeration for defining inital velocity for agents + */ + enum InitVelEnum { + ZERO_INIT_VEL, ///< The agents will start with the zero velocity + PREF_INIT_VEL ///< The agents will start with their preferred velocity + }; + + } // namespace BFSM + + /*! + * @brief Friend function for printing string versions of the PropertyOperand enum + * + * @param out The stream to write the string to. + * @param op The ProperyOperand to write. + * @returns A reference to the output stream. + */ + Logger & operator<<( Logger & out, const BFSM::PropertyOperand op ); + +} // namespace Menge + +#endif // __STATE_ENUM_H__ diff --git a/src/Menge/MengeCore/BFSM/FsmContext.cpp b/src/Menge/MengeCore/BFSM/FsmContext.cpp new file mode 100644 index 00000000..1e0bad3f --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FsmContext.cpp @@ -0,0 +1,138 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "FsmContext.h" +#include "BaseAgent.h" +#include "FSM.h" +#include "State.h" +#include "StateContext.h" +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FsmContext + ///////////////////////////////////////////////////////////////////// + + FsmContext::FsmContext( FSM * fsm ):_fsm(fsm), _currStateCtx(0x0), _drawVC(true), _drawTrans(true) { + } + + ///////////////////////////////////////////////////////////////////// + + FsmContext::~FsmContext() { + StateContextMap::iterator itr = _states.begin(); + for ( ; itr != _states.end(); ++itr ) { + delete itr->second; + } + } + + ///////////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult FsmContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result( false, false ); + + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + + if ( e.type == SDL_KEYDOWN ) { + if ( hasCtrl && e.key.keysym.sym == SDLK_v ) { + _drawVC = !_drawVC; + result.set( true, true ); + } else if ( hasAlt && e.key.keysym.sym == SDLK_t ) { + _drawTrans = !_drawTrans; + result.set( true, true ); + } + } + + if ( ! result.isHandled() && _currStateCtx ) { + result = _currStateCtx->handleKeyboard( e ); + } + return result; + } + + ///////////////////////////////////////////////////////////////////// + + void FsmContext::drawUIGL( const Agents::BaseAgent * agt, int vWidth, int vHeight, bool select ) { + if ( !select ) { + std::stringstream ss; + if ( agt ) { + ss << "BFSM -- agent " << agt->_id << " selected"; + const State * state = _fsm->getCurrentState( agt ); + StateContextMap::const_iterator itr = _states.find( state->getID() ); + if ( itr == _states.end() ) { + ss << "\n in state with no context: " << state->getName() << "(" << state->getID() << ")"; + _currStateCtx = 0x0; + } else { + _currStateCtx = itr->second; + ss << "\n" << _currStateCtx->getUIText( " " ); + } + } else { + _currStateCtx = 0x0; + ss << "BFSM -- no agent selected"; + } + writeToScreen( ss.str(), SceneGraph::TextWriter::RIGHT_TOP, 15, 10.f, 10.f ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void FsmContext::draw3DGL( const Agents::BaseAgent * agt, bool select ) { + if ( !select && agt ) { + const State * state = _fsm->getCurrentState( agt ); + StateContextMap::const_iterator itr = _states.find( state->getID() ); + if ( itr != _states.end() ) { + itr->second->draw3DGL( agt, _drawVC, _drawTrans ); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void FsmContext::addStateContext( size_t id, StateContext * context ) { + assert( _states.find( id ) == _states.end() && "Tried to register multiple contexts for one state" ); + _states[ id ] = context; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/FsmContext.h b/src/Menge/MengeCore/BFSM/FsmContext.h new file mode 100644 index 00000000..b06a1e20 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/FsmContext.h @@ -0,0 +1,159 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FsmContext.h + * @brief The definition of a basic UI context for finite + * state machine objects. + */ + +#ifndef __FSM_CONTEXT_H__ +#define __FSM_CONTEXT_H__ + +#include "CoreConfig.h" +#include "Context.h" +#include "StateContext.h" + +namespace Menge { + + // forward declarations + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + + // Forward declarations + class FSM; + class StateContext; + + /*! + * @brief Base context for finite state machine elements. + * + * This differs from the standard scene graph context by being + * dependent on an input agent. + */ + class MENGE_API FsmContext : public SceneGraph::Context { + public: + /*! + * @brief Constructor. + * + * @param fsm A pointer to the underlying fsm. + * The context will *not* delete the fsm. + */ + FsmContext( FSM * fsm ); + + /*! + * @brief Destructor. + */ + virtual ~FsmContext(); + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Draw UI elements into the context. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void drawUIGL( const Agents::BaseAgent * agt, int vWidth, int vHeight, bool select=false ); + + /*! + * @brief Draw context elements into the 3D world. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, bool select=false ); + + /*! + * @brief Adds a state context to the fsm context. + * + * Each call should provide a unique state. In debug mode, this is tested using an + * assertion. + * + * These contexts will be deleted when the FsmContext is deleted. + * + * @param id The globally unique id of the state. + * @param context A pointer to the context for the given state. + */ + void addStateContext( size_t id, StateContext * context ); + + protected: + /*! + * @brief The underlying finite state machine. + */ + FSM * _fsm; + + /*! + * @brief Determines if the velocity component is displayed in the 3D context. + */ + bool _drawVC; + + /*! + * @brief Determines if the transition is displayed in the 3D context. + */ + bool _drawTrans; + + /*! + * @brief The context for the state currently being displayed. + */ + StateContext * _currStateCtx; + + /*! + * @brief The contexts for the given states. + */ + StateContextMap _states; + + }; + } // namespace BFSM +} // namespace Menge + +#endif // __FSM_CONTEXT_H__ diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.cpp new file mode 100644 index 00000000..1575a02c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.cpp @@ -0,0 +1,123 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorDatabase.h" +#include "Goals/Goal.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalSelector + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSelector::assignGoal( const Agents::BaseAgent * agent ) { + Goal * goal = 0x0; + if ( _persistent ) { + _lock.lockRead(); + HASH_MAP< size_t, Goal * >::iterator itr = _assignedGoals.find( agent->_id ); + if ( itr != _assignedGoals.end() ) { + goal = itr->second; + } + _lock.releaseRead(); + if ( goal ) return goal; + } + + // Either not persistent, or no goal previously assigned + lockResources(); + goal = getGoal( agent ); + if ( goal == 0x0 ) { + logger << Logger::ERR_MSG << "Goal selector unable to create goal for agent " << agent->_id << "."; + throw GoalSelectorException(); + } + try { + goal->assign( agent ); + } catch ( GoalException ) { + logger << Logger::ERR_MSG << "Couldn't assign agent " << agent->_id << " to goal " << goal->getID() << "."; + throw GoalSelectorException(); + } + releaseResources(); + + #ifdef _DEBUG + // In debug mode, always store the assigned goal + _lock.lockWrite(); + _assignedGoals[ agent->_id ] = goal; + _lock.releaseWrite(); + #else + // In release mode, only assign it if persistent + if ( _persistent ) { + _lock.lockWrite(); + _assignedGoals[ agent->_id ] = goal; + _lock.releaseWrite(); + } + #endif + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + void GoalSelector::freeGoal( const Agents::BaseAgent * agent, Goal * goal ) { + #ifdef _DEBUG + _lock.lockWrite(); + assert( _assignedGoals.count( agent->_id ) == 1 && "Trying to free a goal from an agent that hasn't actually been assigned." ); + assert( _assignedGoals[ agent->_id ] == goal && "Trying to free the wrong goal from the agent" ); + _lock.releaseWrite(); + #endif + if ( !_persistent ) { + goal->free(); + #ifdef _DEBUG + _lock.lockWrite(); + _assignedGoals.erase( agent->_id ); + _lock.releaseWrite(); + #endif + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of parsing function + ///////////////////////////////////////////////////////////////////// + + GoalSelector * parseGoalSelector( TiXmlElement * node, const std::string & behaveFldr ) { + return GoalSelectorDB::getInstance( node, behaveFldr ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.h new file mode 100644 index 00000000..1a299af3 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelector.h @@ -0,0 +1,245 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelector.h + * @brief Defines the mechanism for selecting a goal for an agent. + */ + +#ifndef __GOAL_SELECTOR_H__ +#define __GOAL_SELECTOR_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Element.h" +#include "ReadersWriterLock.h" +#include "MengeException.h" +#include + +// forward declaration +class TiXmlElement; + +namespace Menge { + + // forward declaration + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + + // forward declaration + class GoalSet; + class Goal; + + /*! + * @brief Exception class for goal generation. + */ + class MENGE_API GoalSelectorException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + GoalSelectorException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + GoalSelectorException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the goal selector has an error which cannot be + * recovered from. + */ + class GoalSelectorFatalException : public GoalSelectorException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + GoalSelectorFatalException() : MengeException(), GoalSelectorException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + GoalSelectorFatalException( const std::string & s ): MengeException(s), GoalSelectorException(), MengeFatalException() {} + }; + + /////////////////////////////////////////////////////////////////// + + /*! + * @brief The base, abstract class for selecting per-agent goals + */ + class MENGE_API GoalSelector : public Element { + public: + /*! + * @brief Default constructor. + */ + GoalSelector():Element(), _persistent(false), _assignedGoals() {} + + protected: + /*! + * @brief Default virtual destructor. + */ + virtual ~GoalSelector(){} + + public: + /*! + * @brief Uses the goal selector to assign a goal to the + * given agent. + * + * This is the main interface for assiging goals to agents (while + * maintaing bookkeping for capacity and persistence.) It calls + * the GoalSelector::getGoal method to actually determine which + * goal is to be assigned. + * + * @param agent The agent for whom a goal is assigned. + * @returns A pointer to the assigned goal. + */ + Goal * assignGoal( const Agents::BaseAgent * agent ); + + /*! + * @brief Informs the goal selector that the agent is done with + * the goal. + * + * The behavior of this function depends on the persistence of the + * goal selector. If the goal selector is persistent, the goal will + * not actually be *freed* and capacity will remain as indicated. + * If it is not persistent, the goal's capacity will be freed up. + * + * @param agent The agent who is finished using the goal. + * @param goal The goal the agent was previously assigned. + */ + void freeGoal( const Agents::BaseAgent * agent, Goal * goal ); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const = 0; + + /*! + * @brief Gives the instance the opportunity to set the goal set. + * + * This does nothing for instances which don't require a goal set. Otherwise, + * it extracts its required goal set. + * + * @param goalSets A mapping from goal set identifier to goal set pointers. + */ + virtual void setGoalSet( std::map< size_t, GoalSet * > & goalSets ){} + + /*! + * @brief Sets the persistence of the goal. + * + * @param state The new persistence state. + */ + inline void setPersistence( bool state ) { _persistent = state; } + + /*! + * @brief Reports the persistence of the goal. + * + * @returns True if the goal selector is persistent, false otherwise. + */ + inline bool getPersistence() const { return _persistent; } + + protected: + /*! + * @brief Allows the goal selector to lock any resources it + * requires. + * + * This is primarily here so that GoalSelectors which use shared + * resources have a chance to lock them (see SetGoalSelector). + * A call to lockResources should always be followed by a call + * to releeaseResources. + */ + virtual void lockResources() {} + + /*! + * @brief Allows the goal selector to release previously locked + * resources. + * + * Should be used in conjunction with lockResources. + */ + virtual void releaseResources() {} + + /*! + * @brief Determines if the GoalSelector maintains persistent goals. + * + * If the goal selector is persistent, it means that when an agent leaves the + * state with the corresponding goal selector, the goal is not released and + * if the agent returns to the state, it receives its previous goal. + */ + bool _persistent; + + /*! + * @brief A mapping from agent id to assigned goals. + * This will only contain meaningful values in one of two cases: + * - If the selector is persistent. + * - If compiled in debug mode (and then node freeing will + * be tested against this map). + */ + HASH_MAP< size_t, Goal * > _assignedGoals; + + /*! + * @brief The lock to maintain readers-writer access to the + * _assignedGoals + */ + ReadersWriterLock _lock; + }; + + /*! + * @brief Parses a TinyXML element containing a goal selector specification + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new goal selector. + */ + GoalSelector * parseGoalSelector( TiXmlElement * node, const std::string & behaveFldr ); + + } // namespace BFSM +} // namespace Menge +#endif //__GOAL_SELECTOR_H__ diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.cpp new file mode 100644 index 00000000..41f5f1cc --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.cpp @@ -0,0 +1,76 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectorDatabase.h" +#include "GoalSelectors/GoalSelectorIdentity.h" +#include "GoalSelectors/GoalSelectorExplicit.h" +#include "GoalSelectors/GoalSelectorMirror.h" +#include "GoalSelectors/GoalSelectorOffset.h" +#include "GoalSelectors/GoalSelectorRandom.h" +#include "GoalSelectors/GoalSelectorWeighted.h" +#include "GoalSelectors/GoalSelectorNearest.h" +#include "GoalSelectors/GoalSelectorNearestNM.h" +#include "GoalSelectors/GoalSelectorFarthest.h" +#include "GoalSelectors/GoalSelectorFarthestNM.h" +#include "GoalSelectors/GoalSelectorShared.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::GoalSelectorFactory, BFSM::GoalSelector >::getElementName() { return "goal selector"; } + + template <> + void ElementDB< BFSM::GoalSelectorFactory, BFSM::GoalSelector >::addBuiltins() { + addFactory( new BFSM::IdentityGoalSelectorFactory() ); + addFactory( new BFSM::ExplicitGoalSelectorFactory() ); + addFactory( new BFSM::MirrorGoalSelectorFactory() ); + addFactory( new BFSM::OffsetGoalSelectorFactory() ); + addFactory( new BFSM::RandomGoalSelectorFactory() ); + addFactory( new BFSM::WeightedGoalSelectorFactory() ); + addFactory( new BFSM::NearestGoalSelectorFactory() ); + addFactory( new BFSM::FarthestGoalSelectorFactory() ); + addFactory( new BFSM::NearestNMGoalSelectorFactory() ); + addFactory( new BFSM::FarthestNMGoalSelectorFactory() ); + addFactory( new BFSM::SharedGoalSelectorFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.h new file mode 100644 index 00000000..f8e5c875 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorDatabase.h @@ -0,0 +1,77 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorDatabase.h + * @brief Central database for querying available agent goals. + */ + +#ifndef __GOAL_SELECTOR_DATABASE_H__ +#define __GOAL_SELECTOR_DATABASE_H__ + +#include "ElementDatabase.h" +#include "GoalSelectors/GoalSelectorFactory.h" +#include "GoalSelectors/GoalSelector.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The element database for GoalSelectors + */ + typedef ElementDB< GoalSelectorFactory, GoalSelector > GoalSelectorDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + /*! + * @brief Explicit specialization of addBuiltins for the GoalSelector Database + */ + template<> void ElementDB< BFSM::GoalSelectorFactory, BFSM::GoalSelector >::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the GoalSelector Database + */ + template<> std::string ElementDB< BFSM::GoalSelectorFactory, BFSM::GoalSelector >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __GOAL_SELECTOR_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.cpp new file mode 100644 index 00000000..d794df7a --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.cpp @@ -0,0 +1,101 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorExplicit.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + ///////////////////////////////////////////////////////////////////// + // Implementation of ExplicitGoalSelector + ///////////////////////////////////////////////////////////////////// + + ExplicitGoalSelector::ExplicitGoalSelector():GoalSelector() {} + + ///////////////////////////////////////////////////////////////////// + + Goal * ExplicitGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + return _goal; + } + + ///////////////////////////////////////////////////////////////////// + + void ExplicitGoalSelector::setGoalSet( std::map< size_t, GoalSet * > & goalSets ) { + if ( goalSets.count( _goalSetID ) == 1 ) { + GoalSet * gs = goalSets[ _goalSetID ]; + size_t gid = _goalID; + _goal = gs->getGoalByID( gid ); + if ( _goal == 0x0 ) { + std::stringstream ss; + logger << Logger::ERR_MSG << "Goal Selector cannot find targeted goal (" << gid << ") in desired goal set (" << _goalSetID << ")."; + throw GoalSelectorException(); + } + } else { + logger << Logger::ERR_MSG << "Explicit goal selector tried accessing a goal set that doesn't exist: " << _goalSetID << "\n"; + throw GoalSelectorException(); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ExplicitGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + ExplicitGoalSelectorFactory::ExplicitGoalSelectorFactory() : GoalSelectorFactory() { + _goalSetID = _attrSet.addSizeTAttribute( "goal_set", true /*required*/ ); + _goalID = _attrSet.addSizeTAttribute( "goal", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ExplicitGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + ExplicitGoalSelector * gs = dynamic_cast< ExplicitGoalSelector * >( selector ); + assert( gs != 0x0 && "Trying to set explicit goal selector attributes on an incompatible object." ); + + if ( ! GoalSelectorFactory::setFromXML( gs, node, behaveFldr ) ) return false; + + gs->setGoalSetID( _attrSet.getSizeT( _goalSetID ) ); + gs->setGoalID( _attrSet.getSizeT( _goalID ) ); + + return true; + } + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.h new file mode 100644 index 00000000..ddd57107 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorExplicit.h @@ -0,0 +1,189 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorExplicit.h + * @brief The definition of the explicit goal selector - specifying a target + * goal from a set explicitly. + */ + +#ifndef __GOAL_SELECTOR_EXCPLICIT_H__ +#define __GOAL_SELECTOR_EXCPLICIT_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" + +namespace Menge { + + namespace BFSM { + // forward declaration + class Goal; + + /*! + * @brief The explicit goal selector makes extracts a specific goal from + * a specific goal set -- both explicitly stated. + */ + class MENGE_API ExplicitGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + ExplicitGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Gives the instance the opportunity to set the goal set. + * + * This does nothing for instances which don't require a goal set. Otherwise, + * it extracts its required goal set. + * + * @param goalSets A mapping from goal set identifier to goal set pointers. + */ + void setGoalSet( std::map< size_t, GoalSet * > & goalSets ); + + /*! + * @brief Sets the goal set identifier. + * + * @param id The goal set's id that belongs to this selector. + */ + void setGoalSetID( size_t id ) { _goalSetID = id; } + + /*! + * @brief Sets the goal identifier. + * + * @param id The goal's id that belongs to this selector. + */ + void setGoalID( size_t id ) { _goalID = id; } + + protected: + /*! + * @brief The id of the goal set to draw from. + */ + size_t _goalSetID; + + /*! + * @brief The goal associated with this goal selector. + * During parsing, it contains the id of the goal. + * After FSM construction, it contains a pointer to the + * actual goal. + */ + union { + size_t _goalID; ///< The identifier for the goal + Goal * _goal; ///< The pointer to the goal. + }; + }; + + /*! + * @brief Factory for the ExplicitGoalSelector. + */ + class MENGE_API ExplicitGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + ExplicitGoalSelectorFactory(); + + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "explicit"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. The goal an agent gets is " \ + "explicitly enumeraged, goal set and goal id."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new ExplicitGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "goal_set" size_t attribute. + */ + size_t _goalSetID; + + /*! + * @brief The identifier for the "goal" size_t attribute. + */ + size_t _goalID; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_EXCPLICIT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.cpp new file mode 100644 index 00000000..49e101d4 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectorFactory.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + GoalSelectorFactory::GoalSelectorFactory(): ElementFactory< GoalSelector >() { + // register attributes + _persistentID = _attrSet.addBoolAttribute( "persistent", false/*required*/, false/*default*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool GoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< GoalSelector >::setFromXML( selector, node, behaveFldr ) ) return false; + + selector->setPersistence( _attrSet.getBool( _persistentID ) ); + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.h new file mode 100644 index 00000000..5333356d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFactory.h @@ -0,0 +1,98 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorFactory.h + * @brief The factory for parsing xml data and instantiating + * goals. + */ + +#ifndef __GOAL_SELECTOR_FACTORY_H__ +#define __GOAL_SELECTOR_FACTORY_H__ + +#include "CoreConfig.h" +#include "GoalSelectors/GoalSelector.h" +#include + +#include "ElementFactory.h" +#include "GoalSelector.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a goal selector + * and instantiating particular instances. + */ + class MENGE_API GoalSelectorFactory : public ElementFactory< GoalSelector > { + public: + /*! + * @brief Constructor. + */ + GoalSelectorFactory(); + + protected: + /*! + * @brief Given a pointer to a Goal Selector instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Goal Selector's type. + * (i.e. GoalSelectorFactory::thisFactory has already been called and returned true.) + * If sub-classes of GoalSelectorFactory introduce *new* GoalSelector parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param selector A pointer to the goal selector whose attributes are to be set. + * @param node The XML node containing the goal attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "persistent" bool attribute. + */ + size_t _persistentID; + }; + } // namespace BFSM +} // namespace Menge +#endif // __GOAL_SELECTOR_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.cpp new file mode 100644 index 00000000..5cc5fa91 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.cpp @@ -0,0 +1,78 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorFarthest.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + ///////////////////////////////////////////////////////////////////// + // Implementation of FarthestGoalSelector + ///////////////////////////////////////////////////////////////////// + + Goal * FarthestGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "FarthestGoalSelector requires a valid base agent!" ); + const size_t GOAL_COUNT = _goalSet->size(); + if ( GOAL_COUNT == 0 ) { + logger << Logger::ERR_MSG << "FarthestGoalSelector was unable to provide a goal for agent " << agent->_id << ". There were no available goals in the goal set."; + return 0x0; + } + const Vector2 p = agent->_pos; + + Goal * bestGoal; + + bestGoal = _goalSet->getIthGoal( 0 ); + Vector2 disp = bestGoal->getCentroid() - p; + float bestDist = absSq( disp ); + for ( size_t i = 1; i < GOAL_COUNT; ++i ) { + Goal * testGoal = _goalSet->getIthGoal( i ); + disp = testGoal->getCentroid() - p; + float testDist = absSq( disp ); + if ( testDist > bestDist ) { + bestDist = testDist; + bestGoal = testGoal; + } + } + return bestGoal; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.h new file mode 100644 index 00000000..28eb43bb --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthest.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorFarthest.h + * @brief The definition of the farthest goal selector. + */ + +#ifndef __GOAL_SELECTOR_FARTHEST_H__ +#define __GOAL_SELECTOR_FARTHEST_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The nearest goal selector selects the goal from a goal set that + * is farthest to the agent in terms of Euclidian distance. + */ + class MENGE_API FarthestGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + }; + + /*! + * @brief Factory for the FarthestGoalSelector. + */ + class MENGE_API FarthestGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "farthest"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent the goal in the given " \ + "goal set that is *farthest* the agent (in Euclidian distance)."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new FarthestGoalSelector(); } + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_FARTHEST_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.cpp new file mode 100644 index 00000000..7f24eccc --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.cpp @@ -0,0 +1,156 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorFarthestNM.h" +#include "Tasks/NavMeshLocalizerTask.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include "PathPlanner.h" +#include "Route.h" +#include "BaseAgent.h" +#include "os.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FarthestNMGoalSelector + ///////////////////////////////////////////////////////////////////// + + FarthestNMGoalSelector::FarthestNMGoalSelector():SetGoalSelector(),_navMesh(0x0),_localizer(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + Goal * FarthestNMGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + const size_t GOAL_COUNT = _goalSet->size(); + if ( GOAL_COUNT == 0 ) { + logger << Logger::ERR_MSG << "FarthestNMGoalSelector was unable to provide a goal for agent " << agent->_id << ". There were no available goals in the goal set."; + return 0x0; + } + + // 1. Determine which node the agent is in. + unsigned int start = _localizer->updateLocation( agent, true ); + + if ( start == NavMeshLocation::NO_NODE ) { + logger << Logger::ERR_MSG << "Nav Mesh Goal Selector trying to find a goal for an agent who is not on the navigation mesh: Agent " << agent->_id << "."; + throw GoalSelectorException(); + } + + float agentDiameter = 2.f * agent->_radius; + + Goal * bestGoal = 0x0; + float bestDist = 0.f; + + for ( size_t i = 0; i < GOAL_COUNT; ++i ) { + Goal * testGoal = _goalSet->getIthGoal( i ); + unsigned int testNode = _localizer->getNode( testGoal->getCentroid() ); + if ( testNode == NavMeshLocation::NO_NODE ) { + // silently skip it. The centroid is not on the mesh + continue; + } + PortalRoute * route = _localizer->getPlanner()->getRoute( start, testNode, agentDiameter ); + float length = route->getLength(); + if ( length > bestDist ) { + bestDist = length; + bestGoal = testGoal; + } + } + // 2. For each goal in the set, determine which node the center is in (NavMeshLocalizer) + // a. For each start-end goal pair, determine the shortest passable path. (PathPlanner) + // b. based on _getNearest, take the nearest/farthest. + // + if ( bestGoal == 0x0 ) { + logger << Logger::ERR_MSG << "Nav mesh Goal Selector was unable to find a path from agent " << agent->_id << " to any goal in its goal set."; + throw GoalSelectorException(); + } + return bestGoal; + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * FarthestNMGoalSelector::getTask() { + return new NavMeshLocalizerTask( _navMesh->getName(), true /*usePlanner*/ ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of FarthestNMGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + FarthestNMGoalSelectorFactory::FarthestNMGoalSelectorFactory() : SetGoalSelectorFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool FarthestNMGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + FarthestNMGoalSelector * nmgs = dynamic_cast< FarthestNMGoalSelector * >( selector ); + assert( nmgs != 0x0 && "Trying to set attributes of a farthest navigation mesh-based goal selector on an incompatible object" ); + + if ( ! SetGoalSelectorFactory::setFromXML( nmgs, node, behaveFldr ) ) return false; + + // create full path to the nav mesh resource + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + NavMeshPtr nmPtr; + try { + nmPtr = loadNavMesh( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh referenced on line " << node->Row() << "."; + return false; + } + nmgs->setNavMesh( nmPtr ); + // nav mesh localizer + NavMeshLocalizerPtr nmlPtr; + try { + nmlPtr = loadNavMeshLocalizer( fName, true ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh localizer required by the goal selector on line " << node->Row() << "."; + return false; + } + nmgs->setNavMeshLocalizer( nmlPtr ); + + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.h new file mode 100644 index 00000000..ecfca23a --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorFarthestNM.h @@ -0,0 +1,190 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorFarthestNM.h + * @brief The definition of the farthest navigation mesh goal selector. + */ + +#ifndef __GOAL_SELECTOR_FARTHEST_NM_H__ +#define __GOAL_SELECTOR_FARTHEST_NM_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" +#include "NavMesh.h" +#include "NavMeshLocalizer.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The farthest nav mesh goal selector selects the goal from a + * goal set that is farthest to the agent in terms of path length + * through the navigation mesh. + */ + class MENGE_API FarthestNMGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Constructor. + */ + FarthestNMGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Returns a pointer to the nav mesh localizer task. + * + * @returns A pointer to the nav mesh localizer task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual BFSM::Task * getTask(); + + /*! + * @brief Sets the navigation mesh pointer. + * + * @param nm The managed pointer to the navigation mesh. + */ + void setNavMesh( const NavMeshPtr & nm ) { _navMesh = nm; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh + * + * @returns The navigation mesh. + */ + NavMeshPtr getNavMesh() { return _navMesh; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh localizer + * + * @returns The navigation mesh localizer. + */ + NavMeshLocalizerPtr getLocalizer() { return _localizer; } + + /*! + * @brief Sets the navigation mesh localizer pointer. + * + * @param nml The managed pointer to the navigation mesh localizer. + */ + void setNavMeshLocalizer( const NavMeshLocalizerPtr & nml ) { _localizer = nml; } + + protected: + /*! + * @brief The navigation mesh. + */ + NavMeshPtr _navMesh; + + /*! + * @brief The localizer for the navigation mesh. + */ + NavMeshLocalizerPtr _localizer; + + }; + + /*! + * @brief Factory for the FarthestNMGoalSelector. + */ + class MENGE_API FarthestNMGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + FarthestNMGoalSelectorFactory(); + + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "farthest_nav_mesh"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent the goal in the given " \ + "goal set that is *farthest* from the agent based on shortest paths " \ + "through the navigation mesh."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new FarthestNMGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_FARTHEST_NM_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.cpp new file mode 100644 index 00000000..e2e55a55 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorIdentity.h" +#include "Goals/GoalPoint.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of IdentityGoalSelector + ///////////////////////////////////////////////////////////////////// + + IdentityGoalSelector::IdentityGoalSelector():GoalSelector() {} + + ///////////////////////////////////////////////////////////////////// + + Goal * IdentityGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "IdentityGoalGenerator requires a valid base agent!\n" ); + PointGoal * goal = new PointGoal(); + goal->setPosition( agent->_pos ); + return goal; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.h new file mode 100644 index 00000000..2607b83e --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorIdentity.h @@ -0,0 +1,116 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorIdentity.h + * @brief The definition of the "identity" goal selector. + */ + +#ifndef __GOAL_SELECTOR_IDENTITY_H__ +#define __GOAL_SELECTOR_IDENTITY_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The identity goal selector makes a goal out of the agent's + * current position when assigned. The goal is not associated + * with any set and should be destroyed upon being freed. + */ + class MENGE_API IdentityGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + IdentityGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + }; + + /*! + * @brief Factory for the IdentityGoalSelector. + */ + class MENGE_API IdentityGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "identity"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. The goal an agent gets is based on " \ + "its current position when the goal is assigned."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new IdentityGoalSelector(); } + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_IDENTITY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.cpp new file mode 100644 index 00000000..bfc7442c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.cpp @@ -0,0 +1,91 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorMirror.h" +#include "Goals/GoalPoint.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of MirrorGoalSelector + ///////////////////////////////////////////////////////////////////// + + MirrorGoalSelector::MirrorGoalSelector():GoalSelector(),_mirrorX(false),_mirrorY(false) {} + + ///////////////////////////////////////////////////////////////////// + + Goal * MirrorGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "MirrorGoalGenerator requires a valid base agent!\n" ); + const Vector2 p = agent->_pos; + float x = _mirrorX ? -p.x() : p.x(); + float y = _mirrorY ? -p.y() : p.y(); + + PointGoal * goal = new PointGoal(); + goal->setPosition( x, y ); + return goal; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of MirrorGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + MirrorGoalSelectorFactory::MirrorGoalSelectorFactory() : GoalSelectorFactory() { + _mirrorXID = _attrSet.addBoolAttribute( "mirror_x", false /*required*/, false ); + _mirrorYID = _attrSet.addBoolAttribute( "mirror_y", false /*required*/, false ); + } + + ///////////////////////////////////////////////////////////////////// + + bool MirrorGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + MirrorGoalSelector * mgs = dynamic_cast< MirrorGoalSelector * >( selector ); + assert( mgs != 0x0 && "Trying to set mirror goal selector attributes on an incompatible object." ); + + if ( ! GoalSelectorFactory::setFromXML( mgs, node, behaveFldr ) ) return false; + + mgs->setMirrorX( _attrSet.getBool( _mirrorXID ) ); + mgs->setMirrorY( _attrSet.getBool( _mirrorYID ) ); + + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.h new file mode 100644 index 00000000..e6d5920b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorMirror.h @@ -0,0 +1,198 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorMirror.h + * @brief The definition of the "mirror" goal selector. + */ + +#ifndef __GOAL_SELECTOR_MIRROR_H__ +#define __GOAL_SELECTOR_MIRROR_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The mirror goal selector makes a goal by reflecting the agent's + * position around the world's origin. The reflection across the x- + * and y-axes can be individually specified. + * + * Setting the mirror settings to *not* reflect over either axis is akin to creating + * the IdentityGoalSelector. + */ + class MENGE_API MirrorGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + MirrorGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Sets the mirroring of the goal selector. + * + * @param mirrorX Determines if the position is mirrored over the x-axis. + * @param mirrorY Determines if the position is mirrored over the y-axis. + */ + inline void setMirror( bool mirrorX, bool mirrorY ) { _mirrorX = mirrorX; _mirrorY = mirrorY; } + + /*! + * @brief Sets the x-mirroring of the goal selector. + * + * @param mirror Determines if the position is mirrored over the axis. + */ + inline void setMirrorX( bool mirror ) { _mirrorX = mirror; } + + /*! + * @brief Sets the y-mirroring of the goal selector. + * + * @param mirror Determines if the position is mirrored over the axis. + */ + inline void setMirrorY( bool mirror ) { _mirrorY = mirror; } + + /*! + * @brief Returns the mirror x state. + * + * @returns The mirror x state of the selector. + */ + inline bool getMirrorX() const { return _mirrorX; } + + /*! + * @brief Returns the mirror y state. + * + * @returns The mirror y state of the selector. + */ + inline bool getMirrorY() const { return _mirrorY; } + + protected: + /*! + * @brief Determines if the agent's position is reflected over the + * x-axis (true) or not (false). + */ + bool _mirrorX; + + /*! + * @brief Determines if the agent's position is reflected over the + * y-axis (true) or not (false). + */ + bool _mirrorY; + }; + + /*! + * @brief Factory for the MirrorGoalSelector. + */ + class MENGE_API MirrorGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + MirrorGoalSelectorFactory(); + + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "mirror"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. The goal an agent gets is the reflection " \ + "of the agent's position across the world's origin over the "\ + "world's x- and/or y-axes as specified."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new MirrorGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "mirror_x" bool attribute. + */ + size_t _mirrorXID; + + /*! + * @brief The identifier for the "mirror_y" bool attribute. + */ + size_t _mirrorYID; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_MIRROR_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.cpp new file mode 100644 index 00000000..ef439759 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.cpp @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorNearest.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NearestGoalSelector + ///////////////////////////////////////////////////////////////////// + + Goal * NearestGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "NearestGoalGenerator requires a valid base agent!" ); + const size_t GOAL_COUNT = _goalSet->size(); + if ( GOAL_COUNT == 0 ) { + logger << Logger::ERR_MSG << "NearestGoalSelector was unable to provide a goal for agent " << agent->_id << ". There were no available goals in the goal set."; + return 0x0; + } + const Vector2 p = agent->_pos; + + Goal * bestGoal; + + bestGoal = _goalSet->getIthGoal( 0 ); + Vector2 disp = bestGoal->getCentroid() - p; + float bestDist = absSq( disp ); + for ( size_t i = 1; i < GOAL_COUNT; ++i ) { + Goal * testGoal = _goalSet->getIthGoal( i ); + disp = testGoal->getCentroid() - p; + float testDist = absSq( disp ); + if ( testDist < bestDist ) { + bestDist = testDist; + bestGoal = testGoal; + } + } + + return bestGoal; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.h new file mode 100644 index 00000000..169958b8 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearest.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorNearest.h + * @brief The definition of the nearest goal selector. + */ + +#ifndef __GOAL_SELECTOR_NEAREST_H__ +#define __GOAL_SELECTOR_NEAREST_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The nearest goal selector selects the goal from a goal set that + * is nearest to the agent in terms of Euclidian distance. + */ + class MENGE_API NearestGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + }; + + /*! + * @brief Factory for the NearestGoalSelector. + */ + class MENGE_API NearestGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "nearest"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent the goal in the given " \ + "goal set that is *nearest* the agent (in Euclidian distance)."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new NearestGoalSelector(); } + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_NEAREST_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.cpp new file mode 100644 index 00000000..9a455330 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.cpp @@ -0,0 +1,156 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorNearestNM.h" +#include "Tasks/NavMeshLocalizerTask.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include "PathPlanner.h" +#include "Route.h" +#include "BaseAgent.h" +#include "os.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NearestNMGoalSelector + ///////////////////////////////////////////////////////////////////// + + NearestNMGoalSelector::NearestNMGoalSelector():SetGoalSelector(),_navMesh(0x0),_localizer(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + Goal * NearestNMGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + const size_t GOAL_COUNT = _goalSet->size(); + if ( GOAL_COUNT == 0 ) { + logger << Logger::ERR_MSG << "NearestNMGoalSelector was unable to provide a goal for agent " << agent->_id << ". There were no available goals in the goal set."; + return 0x0; + } + + // 1. Determine which node the agent is in. + unsigned int start = _localizer->updateLocation( agent, true ); + + if ( start == NavMeshLocation::NO_NODE ) { + logger << Logger::ERR_MSG << "Nav Mesh Goal Selector trying to find a goal for an agent who is not on the navigation mesh: Agent " << agent->_id << "."; + throw GoalSelectorException(); + } + + float agentDiameter = 2.f * agent->_radius; + + Goal * bestGoal = 0x0; + float bestDist = 1e6f; + + for ( size_t i = 0; i < GOAL_COUNT; ++i ) { + Goal * testGoal = _goalSet->getIthGoal( i ); + unsigned int testNode = _localizer->getNode( testGoal->getCentroid() ); + if ( testNode == NavMeshLocation::NO_NODE ) { + // silently skip it. The centroid is not on the mesh + continue; + } + PortalRoute * route = _localizer->getPlanner()->getRoute( start, testNode, agentDiameter ); + float length = route->getLength(); + if ( length < bestDist ) { + bestDist = length; + bestGoal = testGoal; + } + } + // 2. For each goal in the set, determine which node the center is in (NavMeshLocalizer) + // a. For each start-end goal pair, determine the shortest passable path. (PathPlanner) + // b. based on _getNearest, take the nearest/farthest. + // + if ( bestGoal == 0x0 ) { + logger << Logger::ERR_MSG << "Nav mesh Goal Selector was unable to find a path from agent " << agent->_id << " to any goal in its goal set."; + throw GoalSelectorException(); + } + return bestGoal; + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * NearestNMGoalSelector::getTask() { + return new NavMeshLocalizerTask( _navMesh->getName(), true /*usePlanner*/ ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NearestNMGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + NearestNMGoalSelectorFactory::NearestNMGoalSelectorFactory() : SetGoalSelectorFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool NearestNMGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + NearestNMGoalSelector * smgs = dynamic_cast< NearestNMGoalSelector * >( selector ); + assert( smgs != 0x0 && "Trying to set attributes of a nearest navigation mesh-based goal selector on an incompatible object" ); + + if ( ! SetGoalSelectorFactory::setFromXML( smgs, node, behaveFldr ) ) return false; + + // get the absolute path + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + NavMeshPtr nmPtr; + try { + nmPtr = loadNavMesh( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh referenced on line " << node->Row() << "."; + return false; + } + smgs->setNavMesh( nmPtr ); + // nav mesh localizer + NavMeshLocalizerPtr nmlPtr; + try { + nmlPtr = loadNavMeshLocalizer( fName, true ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh localizer required by the goal selector on line " << node->Row() << "."; + return false; + } + smgs->setNavMeshLocalizer( nmlPtr ); + + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.h new file mode 100644 index 00000000..cd76a915 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorNearestNM.h @@ -0,0 +1,190 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorNearestNM.h + * @brief The definition of the nearest navigation mesh goal selector. + */ + +#ifndef __GOAL_SELECTOR_NEAREST_NM_H__ +#define __GOAL_SELECTOR_NEAREST_NM_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" +#include "NavMesh.h" +#include "NavMeshLocalizer.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The nearest nav mesh goal selector selects the goal from a + * goal set that is nearest to the agent in terms of path length + * through the navigation mesh. + */ + class MENGE_API NearestNMGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Constructor. + */ + NearestNMGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Returns a pointer to the nav mesh localizer task. + * + * @returns A pointer to the nav mesh localizer task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual BFSM::Task * getTask(); + + /*! + * @brief Sets the navigation mesh pointer. + * + * @param nm The managed pointer to the navigation mesh. + */ + void setNavMesh( const NavMeshPtr & nm ) { _navMesh = nm; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh + * + * @returns The navigation mesh. + */ + NavMeshPtr getNavMesh() { return _navMesh; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh localizer + * + * @returns The navigation mesh localizer. + */ + NavMeshLocalizerPtr getLocalizer() { return _localizer; } + + /*! + * @brief Sets the navigation mesh localizer pointer. + * + * @param nml The managed pointer to the navigation mesh localizer. + */ + void setNavMeshLocalizer( const NavMeshLocalizerPtr & nml ) { _localizer = nml; } + + protected: + /*! + * @brief The navigation mesh. + */ + NavMeshPtr _navMesh; + + /*! + * @brief The localizer for the navigation mesh. + */ + NavMeshLocalizerPtr _localizer; + + }; + + /*! + * @brief Factory for the NearestNMGoalSelector. + */ + class MENGE_API NearestNMGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + NearestNMGoalSelectorFactory(); + + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "nearest_nav_mesh"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent the goal in the given " \ + "goal set that is *nearest* to the agent based on shortest paths " \ + "through the navigation mesh."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new NearestNMGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_NEAREST_NM_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.cpp new file mode 100644 index 00000000..4b288003 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.cpp @@ -0,0 +1,91 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorOffset.h" +#include "Goals/GoalPoint.h" +#include "BaseAgent.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of OffsetGoalSelector + ///////////////////////////////////////////////////////////////////// + + OffsetGoalSelector::OffsetGoalSelector():GoalSelector(),_2DVel(0x0) {} + + ///////////////////////////////////////////////////////////////////// + + OffsetGoalSelector::~OffsetGoalSelector() { + if ( _2DVel ) delete _2DVel; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * OffsetGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "OffsetGoalSelector requires a valid base agent!\n" ); + PointGoal * goal = new PointGoal(); + goal->setPosition( agent->_pos + _2DVel->getValue() ); + return goal; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of OffsetGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + OffsetGoalSelectorFactory::OffsetGoalSelectorFactory() : GoalSelectorFactory() { + _offsetID = _attrSet.addVec2DDistAttribute( true, Vector2(0.f, 0.f)/*default-ignored*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool OffsetGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + OffsetGoalSelector * ogs = dynamic_cast< OffsetGoalSelector * >( selector ); + assert( ogs != 0x0 && "Trying to set offset goal selector attributes on an incompatible object." ); + + if ( ! GoalSelectorFactory::setFromXML( ogs, node, behaveFldr ) ) return false; + + ogs->setDistribution( _attrSet.getVec2DGenerator( _offsetID ) ); + + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.h new file mode 100644 index 00000000..d207bccf --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorOffset.h @@ -0,0 +1,162 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorOffset.h + * @brief The definition of the "offset" goal selector. + */ + +#ifndef __GOAL_SELECTOR_OFFSET_H__ +#define __GOAL_SELECTOR_OFFSET_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The offset goal selector makes a goal by applying an offset value + * to the agent's position at assignment time. The offsets can be + * defined with a distribution. + */ + class MENGE_API OffsetGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + OffsetGoalSelector(); + + protected: + /*! + * @brief Destructor. + */ + ~OffsetGoalSelector(); + + public: + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Set the 2D number distribution for the goal selector. + * + * The goal selector takes ownership of the provided 2D number generator + * and will delete it upon its own destruction. + * + * @param gen A pointer to the 2D generator. + */ + void setDistribution( Vec2DGenerator * gen ) { _2DVel = gen; } + + protected: + /*! + * @brief A vector distribution for the offset value. + */ + mutable Vec2DGenerator * _2DVel; + }; + + /*! + * @brief Factory for the OffsetGoalSelector. + */ + class MENGE_API OffsetGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + OffsetGoalSelectorFactory(); + + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "offset"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. The goal an agent gets is the agent's " \ + "position offset by some user-specified 2D distribution."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new OffsetGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the 2D vector generator attribute. + */ + size_t _offsetID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_OFFSET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.cpp new file mode 100644 index 00000000..633cc6ba --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.cpp @@ -0,0 +1,57 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorRandom.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of RandomGoalSelector + ///////////////////////////////////////////////////////////////////// + + Goal * RandomGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "RandomGoalSelector requires a valid base agent!" ); + return _goalSet->getRandomGoal(); + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.h new file mode 100644 index 00000000..f65a71b9 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorRandom.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorRandom.h + * @brief The definition of the random goal selector. + */ + +#ifndef __GOAL_SELECTOR_RANDOM_H__ +#define __GOAL_SELECTOR_RANDOM_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The random goal selector selects a goal from a goal set with + * uniform probability (i.e., it ignores the goal weights). + */ + class MENGE_API RandomGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + }; + + /*! + * @brief Factory for the RandomGoalSelector. + */ + class MENGE_API RandomGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "random"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent a goal drawn randomly " \ + "from a goal set with uniform probability."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new RandomGoalSelector(); } + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_RANDOM_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.cpp new file mode 100644 index 00000000..f9748439 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.cpp @@ -0,0 +1,87 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorRandom.h" +#include "GoalSet.h" +#include "tinyxml.h" +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SetGoalSelector + ///////////////////////////////////////////////////////////////////// + + SetGoalSelector::SetGoalSelector():GoalSelector(), _goalSetID(-1) {} + + ///////////////////////////////////////////////////////////////////// + + void SetGoalSelector::setGoalSet( std::map< size_t, GoalSet * > & goalSets ) { + if ( goalSets.count( _goalSetID ) == 1 ) { + _goalSet = goalSets[ _goalSetID ]; + } else { + logger << Logger::ERR_MSG << "Error selecting goal set " << _goalSetID << " from those defined. It does not exist."; + throw GoalSelectorException(); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SetGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + SetGoalSelectorFactory::SetGoalSelectorFactory() : GoalSelectorFactory() { + _goalSetID = _attrSet.addSizeTAttribute( "goal_set", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool SetGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + SetGoalSelector * sgs = dynamic_cast< SetGoalSelector * >( selector ); + assert( sgs != 0x0 && "Trying to set goal set goal selector attributes on an incompatible object." ); + + if ( ! GoalSelectorFactory::setFromXML( sgs, node, behaveFldr ) ) return false; + + sgs->setGoalSetID( _attrSet.getSizeT( _goalSetID ) ); + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.h new file mode 100644 index 00000000..a10f5b42 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorSet.h @@ -0,0 +1,151 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorSet.h + * @brief The definition of the base class for handling goal selectors which + * operate on single goal sets. + */ + +#ifndef __GOAL_SELECTOR_SET_H__ +#define __GOAL_SELECTOR_SET_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" +#include "GoalSet.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief This is a base class -- not to be instantiated. It provides + * the functional basis for GoalSelectors which use a GoalSet + * as the underlying data structure. + */ + class MENGE_API SetGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + SetGoalSelector(); + + /*! + * @brief Gives the instance the opportunity to set the goal set. + * + * This does nothing for instances which don't require a goal set. Otherwise, + * it extracts its required goal set. + * + * @param goalSets A mapping from goal set identifier to goal set pointers. + */ + void setGoalSet( std::map< size_t, GoalSet * > & goalSets ); + + /*! + * @brief Sets the goal set identifier. + * + * @param id The goal set's id that belongs to this selector. + */ + void setGoalSetID( size_t id ) { _goalSetID = id; } + + protected: + /*! + * @brief Allows the goal selector to lock any resources it + * requires. + * + * This is primarily here so that GoalSelectors which use shared + * resources have a chance to lock them (see SetGoalSelector). + * A call to lockResources should always be followed by a call + * to releeaseResources. + */ + virtual void lockResources() { _goalSet->lockRead(); } + + /*! + * @brief Allows the goal selector to release previously locked + * resources. + * + * Should be used in conjunction with lockResources. + */ + virtual void releaseResources() { _goalSet->releaseRead(); } + + /*! + * @brief The goal set associated with this goal selector. + * During parsing, it contains the id of the goal set. + * After FSM construction, it contains a pointer to the + * actual goal set. + */ + union { + size_t _goalSetID; ///< The identifier for the goal set + GoalSet * _goalSet; ///< The pointer to the goal set. + }; + }; + + /*! + * @brief Factory for the SetGoalSelector. + */ + class MENGE_API SetGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief Constructor. + */ + SetGoalSelectorFactory(); + + protected: + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "goal_set" size_t attribute. + */ + size_t _goalSetID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_SET_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.cpp new file mode 100644 index 00000000..0234b91d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.cpp @@ -0,0 +1,85 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorShared.h" +#include "tinyxml.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SharedGoalSelector + ///////////////////////////////////////////////////////////////////// + + SharedGoalSelector::SharedGoalSelector():GoalSelector(), _stateName(""), _lineNo(0) {} + + ///////////////////////////////////////////////////////////////////// + + Goal * SharedGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + logger << Logger::ERR_MSG << "SharedGoalSelector was left in place to create an agent goal!"; + throw GoalSelectorException(); + return 0x0; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SharedGoalSelectorFactory + ///////////////////////////////////////////////////////////////////// + + bool SharedGoalSelectorFactory::setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const { + SharedGoalSelector * sgs = dynamic_cast< SharedGoalSelector * >( selector ); + assert( sgs != 0x0 && "Trying to set attributes of a shared goal selector on an incompatible object" ); + // NOTE: This does NOT call the parent's setFromXML because it is a special-purpose stub + // It only sub-classes the GoalSelectorFactory so it can sit in the same factory database. + + // get the file name + const char * sNameCStr = node->Attribute( "state_name" ); + if ( sNameCStr ) { + sgs->_stateName = sNameCStr; + sgs->_lineNo = node->Row(); + } else { + logger << Logger::ERR_MSG << "Shared goal selector defined on line " << node->Row() << " is missing the \"state_name\" parameter."; + return false; + } + + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.h new file mode 100644 index 00000000..9b37f801 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorShared.h @@ -0,0 +1,155 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorShared.h + * @brief The definition of the "shared" goal selector. + */ + +#ifndef __GOAL_SELECTOR_SHARED_H__ +#define __GOAL_SELECTOR_SHARED_H__ + +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorFactory.h" + +namespace Menge { + + // forward declarations + namespace Agents { + class SimulatorInterface; + } + + namespace BFSM { + // forward declarations + class SharedGoalSelectorFactory; + class FSM; + class FSMDescrip; + FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ); + + /*! + * @brief The shared goal selector is a stub goal selector + * used strictly internally for bookkeeping. It is used + * to implement shared goal selectors between states. It + * is not intended to be sub-classed.. + */ + class SharedGoalSelector : public GoalSelector { + public: + /*! + * @brief Default constructor + */ + SharedGoalSelector(); + + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + + friend class SharedGoalSelectorFactory; + friend FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ); + protected: + /*! + * @brief The name of the state which will provide the actual + * goal selector instance. + */ + std::string _stateName; + + /*! + * @brief The line number this was defined on (for use with + * logger messages. + */ + int _lineNo; + }; + + /*! + * @brief Factory for the SharedGoalSelector. + */ + class SharedGoalSelectorFactory : public GoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "shared"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector stub. Used to realize the \"shared\" " \ + "goal selector semantics."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new SharedGoalSelector(); } + + /*! + * @brief Given a pointer to a GoalSelector instance, sets the appropriate fields + * from the provided XML node. + * + * @param selector A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal selector attributes. + * @param behaveFldr The path to the behavior file. If the goal selector references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( GoalSelector * selector, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_SHARED_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.cpp b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.cpp new file mode 100644 index 00000000..70e047e4 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.cpp @@ -0,0 +1,57 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalSelectors/GoalSelectorWeighted.h" +#include "Goals/Goal.h" +#include "GoalSet.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of WeightedGoalSelector + ///////////////////////////////////////////////////////////////////// + + Goal * WeightedGoalSelector::getGoal( const Agents::BaseAgent * agent ) const { + assert( agent != 0x0 && "WeightedGoalSelector requires a valid base agent!" ); + return _goalSet->getRandomWeightedGoal(); + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.h b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.h new file mode 100644 index 00000000..743a59e1 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSelectors/GoalSelectorWeighted.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSelectorWeighted.h + * @brief The definition of the weighted random goal selector. + */ + +#ifndef __GOAL_SELECTOR_WEIGHTED_H__ +#define __GOAL_SELECTOR_WEIGHTED_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "GoalSelectors/GoalSelectorSet.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The weighted goal selector selects a goal from a goal set with + * weighted probability (i.e., it uses the user-specified goal weights). + */ + class MENGE_API WeightedGoalSelector : public SetGoalSelector { + public: + /*! + * @brief Interface function for acquiring per-agent goals. + * + * @param agent The agent for whom a goal is extracted. + * @returns A pointer to a goal. + * // TODO: Figure out who owns this goal. + */ + virtual Goal * getGoal( const Agents::BaseAgent * agent ) const; + }; + + /*! + * @brief Factory for the WeightedGoalSelector. + */ + class MENGE_API WeightedGoalSelectorFactory : public SetGoalSelectorFactory { + public: + /*! + * @brief The name of the goal selector type. + * + * The goal selector's name must be unique among all registered goal selectors. + * Each goal selector factory must override this function. + * + * @returns A string containing the unique goal selector name. + */ + virtual const char * name() const { return "weighted"; } + + /*! + * @brief A description of the goal selector. + * + * Each goal selector factory must override this function. + * + * @returns A string containing the goal selector description. + */ + virtual const char * description() const { + return "A goal selector. Assigns the agent a goal drawn randomly " \ + "from a goal set with weighted probability."; + }; + + protected: + /*! + * @brief Create an instance of this class's goal selector. + * + * @returns A pointer to a newly instantiated GoalSelector class. + */ + GoalSelector * instance() const { return new WeightedGoalSelector(); } + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_SELECTOR_WEIGHTED_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSet.cpp b/src/Menge/MengeCore/BFSM/GoalSet.cpp new file mode 100644 index 00000000..c25ebb52 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSet.cpp @@ -0,0 +1,214 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/Goal.h" +#include "GoalSet.h" +#include +#include "fsmCommon.h" +#include +#include "Math/consts.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalSet + ///////////////////////////////////////////////////////////////////// + + GoalSet::GoalSet():_goals(),_goalIDs(),_totalWeight(0.f),_randVal(0.f,1.f) { + } + + ///////////////////////////////////////////////////////////////////// + + GoalSet::~GoalSet() { + std::map< size_t, Goal * >::iterator itr = _goals.begin(); + for ( ; itr != _goals.end(); ++itr ) { + itr->second->destroy(); + } + } + + ///////////////////////////////////////////////////////////////////// + + bool GoalSet::addGoal( size_t id, Goal * goal ) { + bool valid = false; + _lock.lockRead(); + if ( _goals.find( id ) == _goals.end() ) { + valid = true; + goal->_goalSet = this; + _goals[ id ] = goal; + _goalIDs.push_back( id ); + _totalWeight += goal->_weight; + } + _lock.releaseRead(); + return valid; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getGoalByID( size_t id ) { + Goal * goal = 0x0; + std::map< size_t, Goal * >::const_iterator itr = _goals.find( id ); + if ( itr != _goals.end() && itr->second->hasCapacity() ) { + goal = itr->second; + } + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getGoalByIDConcurrent( size_t id ) { + _lock.lockRead(); + Goal * goal = getGoalByID( id ); + _lock.releaseRead(); + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getIthGoal( size_t i ) { + Goal * goal = 0x0; + if ( i < _goalIDs.size() ) { + size_t id = _goalIDs[ i ]; + std::map< size_t, Goal * >::const_iterator itr = _goals.find( id ); + if (itr != _goals.end() && itr->second->hasCapacity() ) { + goal = itr->second; + } + } + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getIthGoalConcurrent( size_t i ) { + _lock.lockRead(); + Goal * goal = getIthGoal( i ); + _lock.releaseRead(); + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + size_t GoalSet::sizeConcurrent() const { + _lock.lockRead(); + size_t s = _goalIDs.size(); + _lock.releaseRead(); + return s; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getRandomGoal() { + Goal * goal = 0x0; + const size_t GOAL_COUNT = _goalIDs.size(); + if ( GOAL_COUNT > 0 ) { + size_t idx = (size_t)( GOAL_COUNT * _randVal.getValue() ); + idx = idx < GOAL_COUNT ? idx : GOAL_COUNT - 1; + size_t id = _goalIDs[ idx ]; + std::map< size_t, Goal * >::const_iterator itr = _goals.find( id ); + assert( itr != _goals.end() && "Somehow failed to get a random goal" ); + goal = itr->second; + } + return goal; + } + + ///////////////////////////////////////////////////////////////////// + + Goal * GoalSet::getRandomWeightedGoal() { + // TODO: Change this to use _goalIDs as the key interface of available goals + Goal * tgtGoal = 0x0; + if ( _goalIDs.size() > 0 ) { + const float TGT_WEIGHT = _totalWeight * _randVal.getValue(); + + std::map< size_t, Goal * >::const_iterator itr = _goals.find( _goalIDs[ 0 ] ); + assert( itr != _goals.end() && "A goalID does not map to a goal" ); + tgtGoal = itr->second; + float accumWeight = tgtGoal->_weight; + for ( size_t i = 1; i < _goalIDs.size(); ++i ) { + if ( accumWeight > TGT_WEIGHT ) break; + itr = _goals.find( _goalIDs[ i ] ); + assert( itr != _goals.end() && "A goalID does not map to a goal" ); + tgtGoal = itr->second; + accumWeight += tgtGoal->_weight; + } + } + return tgtGoal; + } + + ///////////////////////////////////////////////////////////////////// + + void GoalSet::setGoalFull( const Goal * goal ) const { + size_t i = 0; + std::map< size_t, Goal * >::const_iterator itr; + while ( i < _goalIDs.size() ) { + itr = _goals.find( _goalIDs[ i ] ); + assert( itr != _goals.end() && "A goalID does not map to a goal" ); + const Goal * testGoal = itr->second; + if ( testGoal == goal ) { + _totalWeight -= goal->_weight; + _goalIDs.erase( _goalIDs.begin() + i ); // todo: should this just be itr? + break; + } else { + ++i; + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void GoalSet::setGoalAvailable( const Goal * goal ) const { + const size_t GOAL_ID = goal->getID(); + _lock.lockWrite(); + assert( _goals.find( GOAL_ID ) != _goals.end() && "Trying to set a goal available that doesn't belong to the goal set" ); + #ifdef _DEBUG + bool found = false; + for ( size_t i = 0; i < _goalIDs.size(); ++i ) { + if ( _goalIDs[ i ] == GOAL_ID ) { + found = true; + break; + } + } + assert( !found && "Trying to reactivate a goal that was never marked unavailable" ); + #endif + _goalIDs.push_back( GOAL_ID ); + _totalWeight += goal->_weight; + _lock.releaseWrite(); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/GoalSet.h b/src/Menge/MengeCore/BFSM/GoalSet.h new file mode 100644 index 00000000..890a92fc --- /dev/null +++ b/src/Menge/MengeCore/BFSM/GoalSet.h @@ -0,0 +1,229 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalSet.h + * @brief Defines a set of goals + */ + +#ifndef __GOALSET_H__ +#define __GOALSET_H__ + +#include "fsmCommon.h" +#include "ReadersWriterLock.h" +#include + +namespace Menge { + + namespace BFSM { + + // Forward declaration + class Goal; + + ///////////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A set of goals. Maps integer identifiers to instances of goals. + */ + class MENGE_API GoalSet { + public: + /*! + * @brief Default constructor. + */ + GoalSet(); + + /*! + * @brief Destructor. + */ + ~GoalSet(); + + /*! + * @brief Add the given goal with the given id to the set. + * + * @param id The id for the given goal. + * @param goal The goal to add to the set. + * @returns A boolean reporting succes on adding the goal. If the id does not + * already exist in the set, the goal is added and true is + * returned. Otherwise, nothing is changed and false is returned. + * Once a goal is added to the GoalSet, the GoalSet takes responsibility + * for freeing the memory. + */ + bool addGoal( size_t id, Goal * goal ); + + /*! + * @brief Returns the goal with the given user-defined identifier. + * This is the identifier given the behavior specification. + * + * This operation is not thread-safe. It should only be used in a context + * that is known to be "safe". + * + * @param id The identifier of the desired goal. + * @returns A pointer to the desired goal. + * If the goal doesn't exist, NULL is returned. + * Also, if the goal has reached capacity, NULL is returned. + */ + Goal * getGoalByID( size_t id ); + + /*! + * @brief Returns the goal with the given user-defined identifier. + * This is the identifier given the behavior specification. + * + * This operation is thread-safe. But it should not be called in the + * same thread that has already called GoalSet::lockRead. + * + * @param id The identifier of the desired goal. + * @returns A pointer to the desired goal. + * If the goal doesn't exist, NULL is returned. + * Also, if the goal has reached capacity, NULL is returned. + */ + Goal * getGoalByIDConcurrent( size_t id ); + + /*! + * @brief Returns the ith *available* goal (doesn't necessarily correlate + * with the user-defined identifier). Merely the order in which + * the goals are ordered in the set. + * + * This operation is not thread-safe. It should only be used in a context + * that is known to be "safe". + * + * @param i The ith goal in the set -- order is undefined. + * @returns A pointer to the desired goal. + * NULL is returned if the index exceeds the number of *available* goals. + */ + Goal * getIthGoal( size_t i ); + + /*! + * @brief Returns the ith *available* goal (doesn't necessarily correlate + * with the user-defined identifier). Merely the order in which + * the goals are ordered in the set. + * + * This operation is thread-safe. But it should not be called in the + * same thread that has already called GoalSet::lockRead. + * + * @param i The ith goal in the set -- order is undefined. + * @returns A pointer to the desired goal. + * NULL is returned if the index exceeds the number of *available* goals. + */ + Goal * getIthGoalConcurrent( size_t i ); + + /*! + * @brief Reports the number of goals in the set. *Not* thread safe. + * + * @returns The number of goals in the set. + */ + size_t size() const { return _goalIDs.size(); } + + /*! + * @brief Reports the number of goals in the set. Thread safe version. + * + * @returns The number of goals in the set. + */ + size_t sizeConcurrent() const; + + /*! + * @brief Select a goal randomly from the set with all having equal probability. + * + * @returns A pointer to the randomly selected goal + */ + Goal * getRandomGoal(); + + /*! + * @brief Select a goal randomly, based on the relative weights of the goals. + * + * @returns A pointer to the randomly selected goal + */ + Goal * getRandomWeightedGoal(); + + /*! + * @brief Locks the goal set for a read-only operations. + */ + void lockRead() { _lock.lockRead(); } + + /*! + * @brief Unlocks the goal set from read-only operations. + */ + void releaseRead() { _lock.releaseRead(); } + + friend class Goal; + + protected: + /*! + * @brief Informs the goal set that the given goal has reached + * its capacity and should no longer be considered. + */ + void setGoalFull( const Goal * goal ) const; + + /*! + * @brief Informs the goal set that the given goal, previously + * with full capacity, now has capacity to be assigned to + * a new agent. + */ + void setGoalAvailable( const Goal * goal ) const; + + /*! + * @brief The underlying mapping from user-specified goal identifier to goal + */ + std::map< size_t, Goal * > _goals; + + /*! + * @brief A vector of valid identifiers in the goal set. + */ + mutable std::vector< size_t > _goalIDs; + + /*! + * @brief The sum of all goal weights + */ + mutable float _totalWeight; + + /*! + * @brief The random die to select random and weighted goals + */ + UniformFloatGenerator _randVal; + + /*! + * @brief The lock to maintain readers-writer access to the + * structure which control available goals + */ + ReadersWriterLock _lock; + }; + + + } // namespace BFSM +} // namespace Menge + +#endif //__GOALSET_H__ diff --git a/src/Menge/MengeCore/BFSM/Goals/Goal.cpp b/src/Menge/MengeCore/BFSM/Goals/Goal.cpp new file mode 100644 index 00000000..821bfa4c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/Goal.cpp @@ -0,0 +1,113 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/Goal.h" +#include "Goals/GoalDatabase.h" +#include "GoalSet.h" +#include +#include "fsmCommon.h" +#include +#include "Math/consts.h" +#include "graphCommon.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Goal + ///////////////////////////////////////////////////////////////////// + + const size_t Goal::MAX_CAPACITY = -1; // -1 is the biggest value for size_t + + ///////////////////////////////////////////////////////////////////// + + bool Goal::hasCapacity() const { + _lock.lockRead(); + bool result = _population < _capacity; + _lock.releaseRead(); + return result; + } + + ///////////////////////////////////////////////////////////////////// + + void Goal::assign( const Agents::BaseAgent * agent ) { + _lock.lockWrite(); + ++_population; + if ( _population > _capacity ) throw GoalException(); + if ( _population >= _capacity && _goalSet ) _goalSet->setGoalFull( this ); + _lock.releaseWrite(); + } + + ///////////////////////////////////////////////////////////////////// + + void Goal::free() { + _lock.lockWrite(); + if ( _population >= _capacity && _goalSet ) _goalSet->setGoalAvailable( this ); + --_population; + _lock.releaseWrite(); + } + + ///////////////////////////////////////////////////////////////////// + + void Goal::drawGL() const { + glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT); + glDepthMask( GL_FALSE ); + glColor4f( 0.75f, 0.1f, 0.75f, 0.25f ); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + drawGLGeometry(); + + glDisable( GL_BLEND ); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + drawGLGeometry(); + + glPopAttrib(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of Helpers + ///////////////////////////////////////////////////////////////////// + + Goal * parseGoal( TiXmlElement * node, const std::string & behaveFldr ) { + return GoalDB::getInstance( node, behaveFldr ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/Goal.h b/src/Menge/MengeCore/BFSM/Goals/Goal.h new file mode 100644 index 00000000..8858298b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/Goal.h @@ -0,0 +1,332 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Goal.h + * @brief Defines the goal classes for agent behaviors + */ + +#ifndef __GOALS_H__ +#define __GOALS_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Element.h" +#include "ReadersWriterLock.h" +#include "MengeException.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + namespace Agents { + class PrefVelocity; + } + + namespace BFSM { + + // Forward declaration + class GoalSet; + + /*! + * @brief Exception class for BFSM goals. + */ + class MENGE_API GoalException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + GoalException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + GoalException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the goal has an error which cannot be + * recovered from. + */ + class GoalFatalException : public GoalException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + GoalFatalException() : MengeException(), GoalException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + GoalFatalException( const std::string & s ): MengeException(s), GoalException(), MengeFatalException() {} + }; + + ///////////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The base, abstract class defining goals + */ + class MENGE_API Goal : public Element { + public: + /*! + * @brief Basic constructor + * + */ + Goal():Element(),_weight(1.f),_capacity(MAX_CAPACITY),_id(-1),_goalSet(0x0),_population(0){} // -1 is the biggest value for size_t + + protected: + /*! + * @brief Destructor. + */ + virtual ~Goal(){} + + public: + /*! + * @brief Reports the *squared* distance from the given point to the goal. + * + * @param pt The query point. + * @returns The squared distance from the point to the goal. + */ + virtual float squaredDistance( const Vector2 & pt ) const = 0; + + /*! + * @brief Set the preferred velocity directions w.r.t. the goal: left, right, and preferred. + * + * The Agents::PrefVelocity class represents a span of velocities that will reach the goal. + * For a goal that covers a 2D region, the directions in the Agents::PrefVelocity should span the arc + * subtended by the goal from the query point's perspective. Furthermore, it should have sufficient clearance + * for a disk with the given radius to pass through. + * This should be overridden by subclasses to account for their unique geometry. + * + * @param q The query point. + * @param r The radius of clearance. + * @param directions An instance of Agents::PrefVelocity. + */ + virtual void setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const = 0; + + // TODO: Delete this function= transition uses it determine distance to goal + // I would be better off simply returning "squared distance to goal" + /*! + * @brief Returns the closest "target" point in the goal to the given + * query point. + * + * A "valid" target point is the nearest point to the query point that is sufficiently + * inside the goal region that a disk with the given radius is completely inside the goal. + * It need not be literally the *best* value, an approximation is sufficient. + * + * In the case where the goal region is too small to hold the agent, then the "deepest" + * point in the region is a good approximation. + * + * @param q The query point. + * @param r The radius of clearance. + * @returns A 2D position representing the target point. + */ + virtual Vector2 getTargetPoint( const Vector2 & q, float r ) const = 0; + + /*! + * @brief Return the centroid of the goal. + */ + virtual Vector2 getCentroid() const = 0; + + /*! + * @brief Reports if the goal still has capacity. + * + * @returns True if the goal has remaining capacity, false otherwise. + */ + bool hasCapacity() const; + + /*! + * @brief Inform the goal that it has been assigned. + * + * @param agent The agent that has been assigned to this goal. + */ + void assign( const Agents::BaseAgent * agent ); + + /*! + * @brief Inform the goal that an assignment has been removed. + */ + void free(); + + /*! + * @brief Sets this goal's goal set. + * + * @param goalSet A pointer to the goal set to which this goal belongs. + */ + inline void setGoalSet( GoalSet * goalSet ) { _goalSet = goalSet; } + + /*! + * @brief Returns a pointer to this agent's goal set. + * + * A dynamic goal (such as would be created by a hold-position goal + * will return NULL, which means it isn't owned by a goal set and should + * be destroyed when finished. + * + * // TODO: Handle goal sharing and persistence. + * + * @returns A pointer to the goal set to which this goal belongs. + */ + inline GoalSet * getGoalSet() { return _goalSet; } + + /*! + * @brief Returns a const pointer to this agent's goal set. + * + * A dynamic goal (such as would be created by a hold-position goal + * will return NULL, which means it isn't owned by a goal set and should + * be destroyed when finished. + * + * // TODO: Handle goal sharing and persistence. + * + * @returns A const pointer to the goal set to which this goal belongs. + */ + inline const GoalSet * getGoalSet() const { return _goalSet; } + + /*! + * @brief Sets the goal's weight. + * + * @param weight The weight value for this goal. + */ + inline void setWeight( float weight ) { _weight = weight; } + + /*! + * @brief Retrieves the goal's weight. + * + * @returns This goal's weight. + */ + inline float getWeight() const { return _weight; } + + /*! + * @brief Sets the goal's capacity. + * + * @param capacity The target capacity for this goal. + */ + inline void setCapacity( size_t capacity ) { _capacity = capacity; } + + /*! + * @brief Returns this goal's capacity. + * + * @returns The goal's capacity. + */ + inline size_t getCapacity() const { return _capacity; } + + /*! + * @brief Sets the id of the goal. + * + * @param id The goal's new id. + */ + inline void setID( size_t id ) { _id = id; } + + /*! + * @brief Gets the id of the goal. + * + * @returns The goal's id. + */ + inline size_t getID() const { return _id; } + + /*! + * @brief Draws the goal into an OpenGL context. + */ + virtual void drawGL() const; + + /*! + * @brief The maximum capacity any goal can hold. + */ + static const size_t MAX_CAPACITY; + + friend class GoalSet; + + protected: + /*! + * @brief Draws the goal geometry. + */ + virtual void drawGLGeometry() const {} + + /*! + * @brief The relative weight of this goal. + */ + float _weight; + + /*! + * @brief The maximum capacity of this goal. + */ + size_t _capacity; + + /*! + * @brief The id of this goal in its goal set. + */ + size_t _id; + + /*! + * @brief The goal set to which this goal belongs. + */ + GoalSet * _goalSet; + + /*! + * @brief The current "population" of this goal. + * + * In other words, it is the number of times "getGoalPoint" + * has been called on this goal. If a goal is to support + */ + mutable size_t _population; + + /*! + * @brief The lock to maintain readers-writer access to the + * structure which control available goals + */ + ReadersWriterLock _lock; + }; + + /*! + * @brief Parses a TinyXML element containing a goal description + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new goal description (NULL if the definition is invalid). + */ + Goal * parseGoal( TiXmlElement * node, const std::string & behaveFldr ); + + } // namespace BFSM + +} // namespace Menge +#endif //__GOALS_H__ diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalAABB.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalAABB.cpp new file mode 100644 index 00000000..57f2bb06 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalAABB.cpp @@ -0,0 +1,238 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/GoalAABB.h" +#include "graphCommon.h" +#include "PrefVelocity.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of AABBGoal + ///////////////////////////////////////////////////////////////////// + + AABBGoal::AABBGoal():Goal(), _minPt(0.f,0.f), _size(0.f,0.f) {} + + ///////////////////////////////////////////////////////////////////// + + float AABBGoal::squaredDistance( const Vector2 & pt ) const { + // determine quadrant + float minX = _minPt._x; + float maxX = minX + _size._x; + const int xCoord = (int)(pt._x > maxX ) - (int)( pt._x < minX ); + float minY = _minPt._y; + float maxY = minY + _size._y; + const int yCoord = (int)(pt._y > maxY ) - (int)( pt._y < minY ); + + if ( xCoord == 0 && yCoord == 0 ) { + return 0.f; + } else { + // the x- and y- coordinates of the nearest point + float X, Y; + X = ( xCoord == -1 ) * minX + ( xCoord == 1 ) * maxX; + Y = ( yCoord == -1 ) * minY + ( yCoord == 1 ) * maxY; + return absSq( Vector2( X, Y ) - pt ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void AABBGoal::setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const { + // based on the voronoi regions of the AABB + // (-1,1) | (0,1) | (1,1) + // ---------------------------------------- + // | | + // (-1, 0) | (0,0) | (1,0) + // | | + // ---------------------------------------- + // (-1,-1) | (0,-1) | (1,-1) + // + + // the x- and y- coordinates of the nearest point + float X, Y; + // the x- and y-coordintes of the left and right directions + float xL, xR, yL, yR; + + // determine quadrant + const float D = 2.f * r; + float minX = _minPt._x + r; + float maxX = minX + _size._x - D; + const int xCoord = (int)(q._x > maxX ) - (int)( q._x < minX ); + float minY = _minPt._y + r; + float maxY = minY + _size._y - D; + const int yCoord = (int)(q._y > maxY ) - (int)( q._y < minY ); + + if ( xCoord == 0 && yCoord == 0 ) { + // inside the region already + directions.setSingle( Vector2(0.f, 0.f) ); + directions.setTarget( q ); + } else { + int dimensions = 2; + if ( _size._x < D ) { + X = _minPt._x + _size._x * 0.5f; + xL = X; + xR = X; + --dimensions; + } else { + int LMaxXtest = ( yCoord == 1 ) | ( ( xCoord == 1 ) & ( yCoord == 0 ) ); + xL = maxX * LMaxXtest + ( 1 - LMaxXtest ) * minX; + int RMaxXtest = ( yCoord == -1 ) | ( ( xCoord == 1 ) & ( yCoord == 0 ) ); + xR = maxX * RMaxXtest + ( 1 - RMaxXtest ) * minX; + X = ( xCoord == -1 ) * minX + ( xCoord == 1 ) * maxX + ( xCoord == 0 ) * q._x; + } + if ( _size._y < D ) { + Y = _minPt._y + _size._y * 0.5f; + yL = Y; + yR = Y; + --dimensions; + } else { + int LMaxYtest = ( xCoord == -1 ) | ( ( xCoord == 0 ) & ( yCoord == 1 ) ); + yL = maxY * LMaxYtest + ( 1 - LMaxYtest ) * minY; + int RMaxYtest = ( xCoord == 1 ) | ( ( xCoord == 0 ) & ( yCoord == 1 ) ); + yR = maxY * RMaxYtest + ( 1 - RMaxYtest ) * minY; + Y = ( yCoord == -1 ) * minY + ( yCoord == 1 ) * maxY + ( yCoord == 0 ) * q._y; + } + + Vector2 targetPt = Vector2( X, Y ); + directions.setTarget( targetPt ); + Vector2 prefDir( norm( targetPt - q ) ); + if ( dimensions ) { + // there is actually a span + directions.setSpan( norm( Vector2( xL, yL ) - q ), + norm( Vector2( xR, yR ) - q ), + prefDir ); + } else { + directions.setSingle( prefDir ); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 AABBGoal::getTargetPoint( const Vector2 & q, float r ) const { + // based on the voronoi regions of the AABB + // 0 | 1 | 2 + // ---------------------------------------- + // | | + // 3 | 4 | 5 + // | | + // ---------------------------------------- + // 6 | 7 | 8 + // + // Approximated by simply offsetting the sides by r. + + + float X = q._x; + float Y = q._y; + const float D = 2.f * r; + + if ( _size._x < D ) { + X = _minPt._x + _size._x * 0.5f; + } else { + float minX = _minPt._x + r; + float maxX = minX + _size._x - D; + if ( q._x < minX ) { + X = minX; + } else if ( q._x > maxX ) { + X = maxX; + } + } + if ( _size._y < D ) { + Y = _minPt._y + _size._y * 0.5f; + } else { + float minY = _minPt._y + r; + float maxY = minY + _size._y - D; + if ( q._y < minY ) { + Y = minY; + } else if ( q._y > maxY ) { + Y = maxY; + } + } + + return Vector2( X, Y ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 AABBGoal::getCentroid() const { + return _minPt + Vector2( _size.x() * 0.5f, _size.y() * 0.5f ); + } + + ///////////////////////////////////////////////////////////////////// + + void AABBGoal::drawGLGeometry() const { + glBegin( GL_POLYGON ); + glVertex3f( _minPt.x(), 0.f, _minPt.y() ); + glVertex3f( _minPt.x() + _size.x(), 0.f, _minPt.y() ); + glVertex3f( _minPt.x() + _size.x(), 0.f, _minPt.y() + _size.y() ); + glVertex3f( _minPt.x(), 0.f, _minPt.y() + _size.y() ); + glVertex3f( _minPt.x(), 0.f, _minPt.y() ); + glEnd(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of AABBGoalFactory + ///////////////////////////////////////////////////////////////////// + + AABBGoalFactory::AABBGoalFactory() : GoalFactory() { + _minXID = _attrSet.addFloatAttribute( "min_x", true /*required*/ ); + _minYID = _attrSet.addFloatAttribute( "min_y", true /*required*/ ); + _maxXID = _attrSet.addFloatAttribute( "max_x", true /*required*/ ); + _maxYID = _attrSet.addFloatAttribute( "max_y", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool AABBGoalFactory::setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const { + + AABBGoal * aabbGoal = dynamic_cast< AABBGoal * >( goal ); + assert( aabbGoal != 0x0 && "Trying to set AABB goal attributes on an incompatible object." ); + if ( ! GoalFactory::setFromXML( aabbGoal, node, behaveFldr ) ) return false; + + aabbGoal->setMinimum( _attrSet.getFloat( _minXID ), _attrSet.getFloat( _minYID ) ); + aabbGoal->setMaximum( _attrSet.getFloat( _maxXID ), _attrSet.getFloat( _maxYID ) ); + return true; + } + + ///////////////////////////////////////////////////////////////////// + + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalAABB.h b/src/Menge/MengeCore/BFSM/Goals/GoalAABB.h new file mode 100644 index 00000000..4d2ad306 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalAABB.h @@ -0,0 +1,247 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalAABB.h + * @brief The definition of a BFSM axis-aligned bounding box goal. + */ + +#ifndef __GOAL_AABB_H__ +#define __GOAL_AABB_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Goals/Goal.h" +#include "Goals/GoalFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A axis-aligned bounding box goal region with uniform probability + */ + class MENGE_API AABBGoal : public Goal { + public: + /*! + * @brief Default constructor + */ + AABBGoal(); + + /*! + * @brief Reports the *squared* distance from the given point to the goal. + * + * @param pt The query point. + * @returns The squared distance from the point to the goal. + */ + virtual float squaredDistance( const Vector2 & pt ) const; + + /*! + * @brief Set the preferred velocity directions w.r.t. the goal: left, right, and preferred. + * + * The Agents::PrefVelocity class represents a span of velocities that will reach the goal. + * For a goal that covers a 2D region, the directions in the Agents::PrefVelocity should span the arc + * subtended by the goal from the query point's perspective. Furthermore, it should have sufficient clearance + * for a disk with the given radius to pass through. + * This should be overridden by subclasses to account for their unique geometry. + * + * @param q The query point. + * @param r The radius of clearance. + * @param directions An instance of Agents::PrefVelocity. + */ + virtual void setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const; + + /*! + * @brief Returns the closest "target" point in the goal to the given + * query point. + * + * A "valid" target point is the nearest point to the query point that is sufficiently + * inside the goal region that a disk with the given radius is completely inside the goal. + * It need not be literally the *best* value, an approximation is sufficient. + * + * In the case where the goal region is too small to hold the agent, then the "deepest" + * point in the region is a good approximation. + * + * @param q The query point. + * @param r The radius of clearance. + * @returns A 2D position representing the target point. + */ + virtual Vector2 getTargetPoint( const Vector2 & q, float r ) const; + + /*! + * @brief Return the centroid of the goal. + */ + virtual Vector2 getCentroid() const; + + /*! + * @brief Set the AABB's minimum point. + * + * @param x The x-value of the AABB's minimum corner. + * @param y The y-value of the AABB's minimum corner. + */ + inline void setMinimum( float x, float y ) { _minPt.set( x, y ); } + + /*! + * @brief Set the AABB's minimum point. + * + * @param p The position of the AABB's minimum corner. + */ + inline void setMinimum( const Vector2 & p ) { _minPt.set( p ); } + + /*! + * @brief Set the AABB's maximum point. + * + * @param x The x-value of the AABB's maximum corner. + * @param y The y-value of the AABB's maximum corner. + */ + inline void setMaximum( float x, float y ) { _size.set( Vector2( x, y ) - _minPt ); } + + /*! + * @brief Set the AABB's maximum point. + * + * @param p The position of the AABB's maximum corner. + */ + inline void setMaximum( const Vector2 & p ) { _size.set( p - _minPt ); } + + /*! + * @brief Set the AABB's size. + * + * @param w The width (extent along the x-axis) of the AABB. + * @param h The height (extent along the y-axis) of the AABB. + */ + inline void setSize( float w, float h ) { _size.set( w, h ); } + + /*! + * @brief Set the AABB's size. + * + * @param size The size of the AABB (width, height). + */ + inline void setSize( const Vector2 & size ) { _size.set( size ); } + + protected: + /*! + * @brief Draws the goal geometry. + */ + virtual void drawGLGeometry() const; + + /*! + * @brief The minimum point in the box region. + */ + Vector2 _minPt; + + /*! + * @brief The size of the box region beyond the minimum point. + */ + Vector2 _size; + }; + + /*! + * @brief Factory for the AABBGoal. + */ + class MENGE_API AABBGoalFactory : public GoalFactory { + public: + /*! + * @brief Constructor. + */ + AABBGoalFactory(); + + /*! + * @brief The name of the goal type. + * + * The goal's name must be unique among all registered goals. + * Each goal factory must override this function. + * + * @returns A string containing the unique goal name. + */ + virtual const char * name() const { return "AABB"; } + + /*! + * @brief A description of the goal. + * + * Each goal factory must override this function. + * + * @returns A string containing the goal description. + */ + virtual const char * description() const { + return "An agent goal consisting of an axis-aligned bounding box in two-dimensional space"; + }; + + protected: + /*! + * @brief Create an instance of this class's goal. + * + * @returns A pointer to a newly instantiated Goal class. + */ + Goal * instance() const { return new AABBGoal(); } + + /*! + * @brief Given a pointer to a Goal instance, sets the appropriate fields + * from the provided XML node. + * + * @param goal A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "min_x" float attribute. + */ + size_t _minXID; + + /*! + * @brief The identifier for the "min_y" float attribute. + */ + size_t _minYID; + + /*! + * @brief The identifier for the "max_x" float attribute. + */ + size_t _maxXID; + + /*! + * @brief The identifier for the "max_y" float attribute. + */ + size_t _maxYID; + }; + } // namespace BFSM +} // namespace Menge +#endif // __GOAL_AABB_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalCircle.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalCircle.cpp new file mode 100644 index 00000000..a9ecabe8 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalCircle.cpp @@ -0,0 +1,150 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/GoalCircle.h" +#include "shapes.h" +#include "PrefVelocity.h" + +namespace Menge { + + namespace BFSM { + ///////////////////////////////////////////////////////////////////// + // Implementation of CircleGoal + ///////////////////////////////////////////////////////////////////// + + CircleGoal::CircleGoal():Goal(), _center(0.f,0.f), _radius(1.f) {} + + ///////////////////////////////////////////////////////////////////// + + float CircleGoal::squaredDistance( const Vector2 & pt ) const { + float d = abs( pt - _center ); + float perimD = d - _radius; + return perimD * perimD; + } + + ///////////////////////////////////////////////////////////////////// + + void CircleGoal::setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const { + const float TARGET_R = _radius - r; + if ( TARGET_R < 0 ) { + // circle isn't big enough to fit agent -- treat it like a point goal + Vector2 dir( norm( _center - q ) ); + directions.setSingle( dir ); + directions.setTarget( _center ); + } else { + // Circle is large enough to form a span + const float TARGET_R_SQD = TARGET_R * TARGET_R; + Vector2 relPos = _center - q; + const float distSq = absSq( relPos ); + if ( distSq < TARGET_R_SQD ) { + // Goal reached -- I'm inside the effective circle -- current position is the goal + // and no movement is necessary + directions.setSingle( Vector2( 0.f, 0.f ) ); + directions.setTarget( q ); + } else { + // Outside the effective circle, a span is possible. + float leg = sqrtf( distSq - TARGET_R_SQD ); + Vector2 left = Vector2( relPos.x() * leg - relPos.y() * TARGET_R, relPos.x() * TARGET_R + relPos.y() * leg ) / distSq; + Vector2 right = Vector2( relPos.x() * leg + relPos.y() * TARGET_R, -relPos.x() * TARGET_R + relPos.y() * leg ) / distSq; + const float dist = sqrtf( distSq ); + Vector2 dir = relPos / dist; + directions.setSpan( left, right, dir ); + directions.setTarget( q + dir * ( dist - TARGET_R ) ); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 CircleGoal::getTargetPoint( const Vector2 & q, float r ) const { + const float THRESH = _radius - r; + if ( THRESH > 0 ) { + Vector2 disp( q - _center ); + float distSqd = absSq( disp ); + if ( distSqd < THRESH * THRESH ) { + return q; + } else { + float dist = sqrtf( distSqd ); + Vector2 offset = disp * ( THRESH / dist ); + return _center + offset; + } + } else { + return _center; + } + } + + ///////////////////////////////////////////////////////////////////// + + void CircleGoal::drawGLGeometry() const{ + glPushMatrix(); + glTranslatef( _center.x(), 0.f, _center.y() ); + glScalef( _radius, _radius, _radius ); + SceneGraph::Circle::drawUnit(); + glPopMatrix(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of CircleGoalFactory + ///////////////////////////////////////////////////////////////////// + + CircleGoalFactory::CircleGoalFactory() : GoalFactory() { + _xID = _attrSet.addFloatAttribute( "x", true /*required*/ ); + _yID = _attrSet.addFloatAttribute( "y", true /*required*/ ); + _rID = _attrSet.addFloatAttribute( "radius", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool CircleGoalFactory::setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const { + + CircleGoal * cGoal = dynamic_cast< CircleGoal * >( goal ); + assert( cGoal != 0x0 && "Trying to set circle goal attributes on an incompatible object." ); + + if ( ! GoalFactory::setFromXML( cGoal, node, behaveFldr ) ) return false; + + cGoal->setCenter( _attrSet.getFloat( _xID ), _attrSet.getFloat( _yID ) ); + cGoal->setRadius( _attrSet.getFloat( _rID ) ); + + return true; + } + + ///////////////////////////////////////////////////////////////////// + + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalCircle.h b/src/Menge/MengeCore/BFSM/Goals/GoalCircle.h new file mode 100644 index 00000000..f724bdd3 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalCircle.h @@ -0,0 +1,220 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalCircle.h + * @brief The definition of a BFSM circle goal. + */ + +#ifndef __GOAL_CIRCLE_H__ +#define __GOAL_CIRCLE_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Goals/Goal.h" +#include "Goals/GoalFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A circular goal region with uniform probability + */ + class MENGE_API CircleGoal : public Goal { + public: + /*! + * @brief Default constructor + */ + CircleGoal(); + + /*! + * @brief Reports the *squared* distance from the given point to the goal. + * + * @param pt The query point. + * @returns The squared distance from the point to the goal. + */ + virtual float squaredDistance( const Vector2 & pt ) const; + + /*! + * @brief Set the preferred velocity directions w.r.t. the goal: left, right, and preferred. + * + * The Agents::PrefVelocity class represents a span of velocities that will reach the goal. + * For a goal that covers a 2D region, the directions in the Agents::PrefVelocity should span the arc + * subtended by the goal from the query point's perspective. Furthermore, it should have sufficient clearance + * for a disk with the given radius to pass through. + * This should be overridden by subclasses to account for their unique geometry. + * + * @param q The query point. + * @param r The radius of clearance. + * @param directions An instance of Agents::PrefVelocity. + */ + virtual void setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const; + + /*! + * @brief Returns the closest "target" point in the goal to the given + * query point. + * + * A "valid" target point is the nearest point to the query point that is sufficiently + * inside the goal region that a disk with the given radius is completely inside the goal. + * It need not be literally the *best* value, an approximation is sufficient. + * + * In the case where the goal region is too small to hold the agent, then the "deepest" + * point in the region is a good approximation. + * + * @param q The query point. + * @param r The radius of clearance. + * @returns A 2D position representing the target point. + */ + virtual Vector2 getTargetPoint( const Vector2 & q, float r ) const; + + /*! + * @brief Return the centroid of the goal. + */ + virtual Vector2 getCentroid() const { return _center; } + + /*! + * @brief Sets the circle's center position. + * + * @param x The x-value of the center position. + * @param y The y-value of the center position. + */ + inline void setCenter( float x, float y ) { _center.set( x, y ); } + + /*! + * @brief Sets the circle's center position. + * + * @param p The new center position. + */ + inline void setCenter( const Vector2 & p ) { _center.set( p ); } + + /*! + * @brief Sets the circle's radius. + * + * @param r The circle's new radius value. + */ + inline void setRadius( float r ) { _radius = r; } + + protected: + /*! + * @brief Draws the goal geometry. + */ + virtual void drawGLGeometry() const; + + /*! + * @brief The center of the goal circle. + */ + Vector2 _center; + + /*! + * @brief The radius of the goal circle. + */ + float _radius; + }; + + /*! + * @brief Factory for the CircleGoal. + */ + class MENGE_API CircleGoalFactory : public GoalFactory { + public: + /*! + * @brief Constructor + */ + CircleGoalFactory(); + + /*! + * @brief The name of the goal type. + * + * The goal's name must be unique among all registered goals. + * Each goal factory must override this function. + * + * @returns A string containing the unique goal name. + */ + virtual const char * name() const { return "circle"; } + + /*! + * @brief A description of the goal. + * + * Each goal factory must override this function. + * + * @returns A string containing the goal description. + */ + virtual const char * description() const { + return "An agent goal consisting of a circle in two-dimensional space"; + }; + + protected: + /*! + * @brief Create an instance of this class's goal. + * + * @returns A pointer to a newly instantiated Goal class. + */ + Goal * instance() const { return new CircleGoal(); } + + /*! + * @brief Given a pointer to a Goal instance, sets the appropriate fields + * from the provided XML node. + * + * @param goal A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "x" float attribute. + */ + size_t _xID; + + /*! + * @brief The identifier for the "y" float attribute. + */ + size_t _yID; + + /*! + * @brief The identifier for the "radius" float attribute. + */ + size_t _rID; + }; + } // namespace BFSM +} // namespace Menge + +#endif //__GOAL_CIRCLE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.cpp new file mode 100644 index 00000000..245d10bc --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.cpp @@ -0,0 +1,62 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalDatabase.h" +#include "Goals/GoalPoint.h" +#include "Goals/GoalCircle.h" +#include "Goals/GoalAABB.h" +#include "Goals/GoalOBB.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::GoalFactory, BFSM::Goal >::getElementName() { return "goal"; } + + template <> + void ElementDB< BFSM::GoalFactory, BFSM::Goal >::addBuiltins() { + addFactory( new BFSM::PointGoalFactory() ); + addFactory( new BFSM::CircleGoalFactory() ); + addFactory( new BFSM::AABBGoalFactory() ); + addFactory( new BFSM::OBBGoalFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.h b/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.h new file mode 100644 index 00000000..2678d4e5 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalDatabase.h @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalDatabase.h + * @brief Central database for querying available agent goals. + */ + +#ifndef __GOAL_DATABASE_H__ +#define __GOAL_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Goals/GoalFactory.h" +#include "Goals/Goal.h" + +namespace Menge { + + namespace BFSM { + + /*! + * @brief The database of registered goal implementations. + */ + typedef ElementDB< GoalFactory, Goal > GoalDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + /*! + * @brief Explicit specialization of addBuiltins for the Goal Database + */ + template<> void ElementDB< BFSM::GoalFactory, BFSM::Goal >::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the Goal Database + */ + template<> std::string ElementDB< BFSM::GoalFactory, BFSM::Goal >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + + + +#endif // __GOAL_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalFactory.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalFactory.cpp new file mode 100644 index 00000000..c9ab5eb2 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalFactory.cpp @@ -0,0 +1,69 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GoalFactory.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalFactory + ///////////////////////////////////////////////////////////////////// + + GoalFactory::GoalFactory(): ElementFactory< Goal >() { + // register attributes + _idID = _attrSet.addSizeTAttribute( "id", true/*required*/, 0/*default*/ ); + _capacityID = _attrSet.addSizeTAttribute( "capacity", false/*required*/, std::numeric_limits< size_t >::max()/*default*/ ); + _weightID = _attrSet.addFloatAttribute( "weight", false /*required*/, 1.f ); + } + + ///////////////////////////////////////////////////////////////////// + + bool GoalFactory::setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const { + if ( !ElementFactory< Goal >::setFromXML( goal, node, behaveFldr ) ) return false; + + goal->setID( _attrSet.getSizeT( _idID ) ); + goal->setCapacity( _attrSet.getSizeT( _capacityID ) ); + goal->setWeight( _attrSet.getFloat( _weightID ) ); + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalFactory.h b/src/Menge/MengeCore/BFSM/Goals/GoalFactory.h new file mode 100644 index 00000000..0ca56adc --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalFactory.h @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalFactory.h + * @brief The factory for parsing xml data and instantiating + * goals. + */ + +#ifndef __GOAL_FACTORY_H__ +#define __GOAL_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "Goals/Goal.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a goal + * and instantiating particular instances. + */ + class MENGE_API GoalFactory : public ElementFactory< Goal > { + public: + /*! + * @brief Constructor. + */ + GoalFactory(); + + protected: + /*! + * @brief Given a pointer to a Goal instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Goal's type. + * (i.e. GoalFactory::thisFactory has already been called and returned true.) + * If sub-classes of GoalFactory introduce *new* Goal parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param goal A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the goal attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "id" size_t attribute. + */ + size_t _idID; + + /*! + * @brief The identifier for the "capacity" size_t attribute. + */ + size_t _capacityID; + + /*! + * @brief The identifier for the "weight" size_t attribute. + */ + size_t _weightID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalOBB.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalOBB.cpp new file mode 100644 index 00000000..468b143a --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalOBB.cpp @@ -0,0 +1,290 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/GoalOBB.h" +#include "graphCommon.h" +#include "PrefVelocity.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of OBBGoal + ///////////////////////////////////////////////////////////////////// + + OBBGoal::OBBGoal():Goal(), _pivot(0.f,0.f), _size(0.f,0.f), _rot0(1.f,0.f), _rot1(0.f,1.f) {} + + ///////////////////////////////////////////////////////////////////// + + float OBBGoal::squaredDistance( const Vector2 & pt ) const { + // First rotate so that the OBB is an AABB then use the same logic as + // with the AABB + Vector2 disp = pt - _pivot; + float cosTheta = _rot0._x; + float sinTheta = _rot1._x; + // the LOCAL x- and y- coordinates of the nearest point, initialized to the + // local value of the query point. + float X = disp.x() * cosTheta + disp.y() * sinTheta; + float Y = disp.y() * cosTheta - disp.x() * sinTheta; + + // determine quadrant + const float minX = 0.f; + const float maxX = _size._x; + const int xCoord = (int)(X > maxX ) - (int)( X < minX ); + const float minY = 0.f; + const float maxY = _size._y; + const int yCoord = (int)(Y > maxY ) - (int)( Y < minY ); + + if ( xCoord == 0 && yCoord == 0 ) { + return 0.f; + } else { + // the x- and y- coordinates of the nearest point + X = ( xCoord == -1 ) * minX + ( xCoord == 1 ) * maxX; + Y = ( yCoord == -1 ) * minY + ( yCoord == 1 ) * maxY; + return absSq( Vector2( X, Y ) - disp ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void OBBGoal::setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const { + // First rotate so that the OBB is an AABB then use the same logic as + // with the AABB + Vector2 disp = q - _pivot; + float cosTheta = _rot0._x; + float sinTheta = _rot1._x; + // the LOCAL x- and y- coordinates of the nearest point, initialized to the + // local value of the query point. + float X = disp.x() * cosTheta + disp.y() * sinTheta; + float Y = disp.y() * cosTheta - disp.x() * sinTheta; + + // based on the voronoi regions of the AABB + // (-1,1) | (0,1) | (1,1) + // ---------------------------------------- + // | | + // (-1, 0) | (0,0) | (1,0) + // | | + // ---------------------------------------- + // (-1,-1) | (0,-1) | (1,-1) + // + + // the x- and y-coordintes of the left and right directions + float xL, xR, yL, yR; + + // determine quadrant + const float D = 2.f * r; + const float minX = r; + const float maxX = _size._x - r; + const int xCoord = (int)(X > maxX ) - (int)( X < minX ); + const float minY = r; + const float maxY = _size._y - r; + const int yCoord = (int)(Y > maxY ) - (int)( Y < minY ); + + if ( xCoord == 0 && yCoord == 0 ) { + // inside the region already + directions.setSingle( Vector2(0.f, 0.f) ); + directions.setTarget( q ); + } else { + int dimensions = 2; + if ( _size._x < D ) { + X = _size._x * 0.5f; + xL = X; + xR = X; + --dimensions; + } else { + int LMaxXtest = ( yCoord == 1 ) | ( ( xCoord == 1 ) & ( yCoord == 0 ) ); + xL = maxX * LMaxXtest + ( 1 - LMaxXtest ) * minX; + int RMaxXtest = ( yCoord == -1 ) | ( ( xCoord == 1 ) & ( yCoord == 0 ) ); + xR = maxX * RMaxXtest + ( 1 - RMaxXtest ) * minX; + X = ( xCoord == -1 ) * minX + ( xCoord == 1 ) * maxX + ( xCoord == 0 ) * X; + } + if ( _size._y < D ) { + Y = _size._y * 0.5f; + yL = Y; + yR = Y; + --dimensions; + } else { + int LMaxYtest = ( xCoord == -1 ) | ( ( xCoord == 0 ) & ( yCoord == 1 ) ); + yL = maxY * LMaxYtest + ( 1 - LMaxYtest ) * minY; + int RMaxYtest = ( xCoord == 1 ) | ( ( xCoord == 0 ) & ( yCoord == 1 ) ); + yR = maxY * RMaxYtest + ( 1 - RMaxYtest ) * minY; + Y = ( yCoord == -1 ) * minY + ( yCoord == 1 ) * maxY + ( yCoord == 0 ) * Y; + } + + Vector2 localPt( X, Y ); + Vector2 targetPt( _pivot + Vector2( localPt * _rot0, localPt * _rot1 ) ); + directions.setTarget( targetPt ); + Vector2 prefDir( norm( targetPt - q ) ); + if ( dimensions ) { + // there is actually a span + localPt.set( xL, yL ); + Vector2 leftPt( _pivot + Vector2( localPt * _rot0, localPt * _rot1 ) ); + localPt.set( xR, yR ); + Vector2 rightPt( _pivot + Vector2( localPt * _rot0, localPt * _rot1 ) ); + directions.setSpan( norm( leftPt - q ), + norm( rightPt - q ), + prefDir ); + } else { + directions.setSingle( prefDir ); + } + } + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 OBBGoal::getTargetPoint( const Vector2 & q, float r ) const { + // First rotate so that the OBB is an AABB then use the same logic as + // with the AABB + Vector2 disp = q - _pivot; + float cosTheta = _rot0._x; + float sinTheta = _rot1._x; + float X = disp.x() * cosTheta + disp.y() * sinTheta; + float Y = disp.y() * cosTheta - disp.x() * sinTheta; + + // based on the voronoi regions of the AABB + // 0 | 1 | 2 + // ---------------------------------------- + // | | + // 3 | 4 | 5 + // | | + // ---------------------------------------- + // 6 | 7 | 8 + // + // Approximated by simply offsetting the sides by r. + + + const float D = 2.f * r; + + if ( _size._x < D ) { + X = _size._x * 0.5f; + } else { + float minX = r; + float maxX = _size._x - r; + if ( X < minX ) { + X = minX; + } else if ( X > maxX ) { + X = maxX; + } + } + if ( _size._y < D ) { + Y = _size._y * 0.5f; + } else { + float minY = r; + float maxY = _size._y - r; + if ( Y < minY ) { + Y = minY; + } else if ( Y > maxY ) { + Y = maxY; + } + } + + Vector2 localPt( X, Y ); + + return _pivot + Vector2( localPt * _rot0, localPt * _rot1 ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 OBBGoal::getCentroid() const { + return _pivot + _rot0 * ( _size.x() * 0.5f ) + _rot1 * ( _size.y() * 0.5f ); + } + + ///////////////////////////////////////////////////////////////////// + + void OBBGoal::drawGLGeometry() const{ + Vector2 c( _size.x(), 0.f ); + Vector2 c1( c * _rot0, c * _rot1 ); + c.set( _size ); + Vector2 c2( c * _rot0, c * _rot1 ); + c.set( 0.f, _size.y() ); + Vector2 c3( c * _rot0, c * _rot1 ); + + glPushMatrix(); + glTranslatef( _pivot.x(), 0.f, _pivot.y() ); + glBegin( GL_POLYGON ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( c1.x(), 0.f, c1.y() ); + glVertex3f( c2.x(), 0.f, c2.y() ); + glVertex3f( c3.x(), 0.f, c3.y() ); + glVertex3f( 0.f, 0.f, 0.f ); + glEnd(); + glPopMatrix(); + } + + ///////////////////////////////////////////////////////////////////// + + void OBBGoal::setRotation( float angle ) { + float cTheta = cos( angle ); + float sTheta = sin( angle ); + _rot0.set( cTheta, -sTheta ); + _rot1.set( sTheta, cTheta ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of OBBGoalFactory + ///////////////////////////////////////////////////////////////////// + + OBBGoalFactory::OBBGoalFactory() : GoalFactory() { + _xID = _attrSet.addFloatAttribute( "x", true /*required*/ ); + _yID = _attrSet.addFloatAttribute( "y", true /*required*/ ); + _wID = _attrSet.addFloatAttribute( "width", true /*required*/ ); + _hID = _attrSet.addFloatAttribute( "height", true /*required*/ ); + _aID = _attrSet.addFloatAttribute( "angle", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool OBBGoalFactory::setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const { + + OBBGoal * obbGoal = dynamic_cast< OBBGoal * >( goal ); + assert( obbGoal != 0x0 && "Trying to set OBB goal attributes on an incompatible object." ); + if ( ! GoalFactory::setFromXML( obbGoal, node, behaveFldr ) ) return false; + + obbGoal->setPivot( _attrSet.getFloat( _xID ), _attrSet.getFloat( _yID ) ); + obbGoal->setSize( _attrSet.getFloat( _wID ), _attrSet.getFloat( _hID ) ); + obbGoal->setRotation( _attrSet.getFloat( _aID ) * DEG_TO_RAD ); + + return true; + } + + ///////////////////////////////////////////////////////////////////// + + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalOBB.h b/src/Menge/MengeCore/BFSM/Goals/GoalOBB.h new file mode 100644 index 00000000..ad239f13 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalOBB.h @@ -0,0 +1,264 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalOBB.h + * @brief The definition of a BFSM oriented bounding box goal. + */ + +#ifndef __GOAL_OBB_H__ +#define __GOAL_OBB_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Goals/Goal.h" +#include "Goals/GoalFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief An oriented bounding box goal region with uniform probability. + * + * The oriented bounding box (OBB) is defined by a pivot point, a size, and an orientation. + * An OBB with no rotation is the same as an AABB whose minimum point is the pivot + * point and which extends along the x-axis and the y-axis the given width and + * height, respectively. Positive angle causes counter-clockwise rotation. + */ + class MENGE_API OBBGoal : public Goal { + public: + /*! + * @brief Default constructor + */ + OBBGoal(); + + /*! + * @brief Reports the *squared* distance from the given point to the goal. + * + * @param pt The query point. + * @returns The squared distance from the point to the goal. + */ + virtual float squaredDistance( const Vector2 & pt ) const; + + /*! + * @brief Set the preferred velocity directions w.r.t. the goal: left, right, and preferred. + * + * The Agents::PrefVelocity class represents a span of velocities that will reach the goal. + * For a goal that covers a 2D region, the directions in the Agents::PrefVelocity should span the arc + * subtended by the goal from the query point's perspective. Furthermore, it should have sufficient clearance + * for a disk with the given radius to pass through. + * This should be overridden by subclasses to account for their unique geometry. + * + * @param q The query point. + * @param r The radius of clearance. + * @param directions An instance of Agents::PrefVelocity. + */ + virtual void setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const; + + /*! + * @brief Returns the closest "target" point in the goal to the given + * query point. + * + * A "valid" target point is the nearest point to the query point that is sufficiently + * inside the goal region that a disk with the given radius is completely inside the goal. + * It need not be literally the *best* value, an approximation is sufficient. + * + * In the case where the goal region is too small to hold the agent, then the "deepest" + * point in the region is a good approximation. + * + * @param q The query point. + * @param r The radius of clearance. + * @returns A 2D position representing the target point. + */ + virtual Vector2 getTargetPoint( const Vector2 & q, float r ) const; + + /*! + * @brief Return the centroid of the goal. + */ + virtual Vector2 getCentroid() const; + + /*! + * @brief Set the OBB's pivot point. + * + * @param x The x-value of the OBB's pivot point. + * @param y The y-value of the OBB's pivot point. + */ + inline void setPivot( float x, float y ) { _pivot.set( x, y ); } + + /*! + * @brief Set the OBB's pivot point. + * + * @param p The position of the OBB's pivot point. + */ + inline void setPivot( const Vector2 & p ) { _pivot.set( p ); } + + /*! + * @brief Set the AABB's size. + * + * @param w The width (extent along the x-axis) of the AABB. + * @param h The height (extent along the y-axis) of the AABB. + */ + inline void setSize( float w, float h ) { _size.set( w, h ); } + + /*! + * @brief Set the AABB's size. + * + * @param size The size of the AABB (width, height). + */ + inline void setSize( const Vector2 & size ) { _size.set( size ); } + + /*! + * @brief Set the OBB's rotation angle (in radians). + * + * @param angle The angle of rotation (in radians). + */ + void setRotation( float angle ); + + protected: + /*! + * @brief Draws the goal geometry. + */ + virtual void drawGLGeometry() const; + + /*! + * @brief The minimum point in the box region. + */ + Vector2 _pivot; + + /*! + * @brief The size of the box region beyond the minimum point. + */ + Vector2 _size; + + /*! + * @brief The first column of the rotation matrix + * A point, p, can be rotated to the box's + * orientation as: Vector( p * _rot0, p * _rot1 ); + */ + Vector2 _rot0; + + /*! + * @brief The second column of the rotation matrix + * A point, p, can be rotated to the box's + * orientation as: Vector( p * _rot0, p * _rot1 ); + */ + Vector2 _rot1; + }; + + /*! + * @brief Factory for the OBBGoal. + */ + class MENGE_API OBBGoalFactory : public GoalFactory { + public: + /*! + * @brief Constructor. + */ + OBBGoalFactory(); + + /*! + * @brief The name of the goal type. + * + * The goal's name must be unique among all registered goals. + * Each goal factory must override this function. + * + * @returns A string containing the unique goal name. + */ + virtual const char * name() const { return "OBB"; } + + /*! + * @brief A description of the goal. + * + * Each goal factory must override this function. + * + * @returns A string containing the goal description. + */ + virtual const char * description() const { + return "An agent goal consisting of an oriented bounding box in two-dimensional space"; + }; + + protected: + /*! + * @brief Create an instance of this class's goal. + * + * @returns A pointer to a newly instantiated Goal class. + */ + Goal * instance() const { return new OBBGoal(); } + + /*! + * @brief Given a pointer to a Goal instance, sets the appropriate fields + * from the provided XML node. + * + * @param goal A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "x" float attribute. + */ + size_t _xID; + + /*! + * @brief The identifier for the "y" float attribute. + */ + size_t _yID; + + /*! + * @brief The identifier for the "width" float attribute. + */ + size_t _wID; + + /*! + * @brief The identifier for the "height" float attribute. + */ + size_t _hID; + + /*! + * @brief The identifier for the "angle" float attribute. + */ + size_t _aID; + }; + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_OBB_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalPoint.cpp b/src/Menge/MengeCore/BFSM/Goals/GoalPoint.cpp new file mode 100644 index 00000000..7f9851d5 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalPoint.cpp @@ -0,0 +1,92 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Goals/GoalPoint.h" +#include "PrefVelocity.h" +#include "graphCommon.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PointGoal + ///////////////////////////////////////////////////////////////////// + + PointGoal::PointGoal():Goal(),_point(0.f,0.f) {} + + ///////////////////////////////////////////////////////////////////// + + void PointGoal::setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const { + Vector2 dir( norm( _point - q ) ); + directions.setSingle( dir ); + directions.setTarget( _point ); + } + + ///////////////////////////////////////////////////////////////////// + + void PointGoal::drawGL() const{ + glBegin( GL_POINTS ); + glVertex3f( _point.x(), 0.f, _point.y() ); + glEnd(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of PointGoalFactory + ///////////////////////////////////////////////////////////////////// + + PointGoalFactory::PointGoalFactory() : GoalFactory() { + _xID = _attrSet.addFloatAttribute( "x", true /*required*/ ); + _yID = _attrSet.addFloatAttribute( "y", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool PointGoalFactory::setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const { + + PointGoal * pGoal = dynamic_cast< PointGoal * >( goal ); + assert( pGoal != 0x0 && "Trying to set point goal attributes on an incompatible object." ); + + if ( ! GoalFactory::setFromXML( pGoal, node, behaveFldr ) ) return false; + + pGoal->setPosition( _attrSet.getFloat( _xID ), _attrSet.getFloat( _yID ) ); + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Goals/GoalPoint.h b/src/Menge/MengeCore/BFSM/Goals/GoalPoint.h new file mode 100644 index 00000000..ef29df5c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Goals/GoalPoint.h @@ -0,0 +1,204 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GoalPoint.h + * @brief The definition of a BFSM point goal. + */ + +#ifndef __GOAL_POINT_H__ +#define __GOAL_POINT_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Goals/Goal.h" +#include "Goals/GoalFactory.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A simple point goal. The goal is trivially this point. + */ + class MENGE_API PointGoal : public Goal { + public: + /*! + * @brief Default constructor + */ + PointGoal(); + + /*! + * @brief Reports the *squared* distance from the given point to the goal. + * + * @param pt The query point. + * @returns The squared distance from the point to the goal. + */ + virtual float squaredDistance( const Vector2 & pt ) const { return absSq( pt - _point ); } + + /*! + * @brief Set the preferred velocity directions w.r.t. the goal: left, right, and preferred. + * + * The Agents::PrefVelocity class represents a span of velocities that will reach the goal. + * For a goal that covers a 2D region, the directions in the Agents::PrefVelocity should span the arc + * subtended by the goal from the query point's perspective. Furthermore, it should have sufficient clearance + * for a disk with the given radius to pass through. + * This should be overridden by subclasses to account for their unique geometry. + * + * @param q The query point. + * @param r The radius of clearance. + * @param directions An instance of Agents::PrefVelocity. + */ + virtual void setDirections( const Vector2 & q, float r, Agents::PrefVelocity & directions ) const; + + /*! + * @brief Returns the closest "target" point in the goal to the given + * query point. + * + * A "valid" target point is the nearest point to the query point that is sufficiently + * inside the goal region that a disk with the given radius is completely inside the goal. + * It need not be literally the *best* value, an approximation is sufficient. + * + * In the case where the goal region is too small to hold the agent, then the "deepest" + * point in the region is a good approximation. + * + * @param q The query point. + * @param r The radius of clearance. + * @returns A 2D position representing the target point. + */ + virtual Vector2 getTargetPoint( const Vector2 & q, float r ) const { return _point; } + + /*! + * @brief Return the centroid of the goal. + */ + virtual Vector2 getCentroid() const { return _point; } + + /*! + * @brief Draws the goal into an OpenGL context. + */ + virtual void drawGL() const; + + /*! + * @brief Sets the goal's position. + * + * @param p The position value. + */ + void setPosition( const Vector2 & p ) { _point.set( p ); } + + /*! + * @brief Sets the goal's position. + * + * @param x The x-value of the goal position. + * @param y The y-value of the goal position. + */ + void setPosition( float x, float y ) { _point.set( x, y ); } + + protected: + /*! + * @brief The point for this goal. + */ + Vector2 _point; + }; + + /*! + * @brief Factory for the PointGoal. + */ + class MENGE_API PointGoalFactory : public GoalFactory { + public: + /*! + * @brief Constructor. + */ + PointGoalFactory(); + + /*! + * @brief The name of the goal type. + * + * The goal's name must be unique among all registered goals. + * Each goal factory must override this function. + * + * @returns A string containing the unique goal name. + */ + virtual const char * name() const { return "point"; } + + /*! + * @brief A description of the goal. + * + * Each goal factory must override this function. + * + * @returns A string containing the goal description. + */ + virtual const char * description() const { + return "An agent goal consisting of a single point in two-dimensional space"; + }; + + protected: + /*! + * @brief Create an instance of this class's goal. + * + * @returns A pointer to a newly instantiated Goal class. + */ + Goal * instance() const { return new PointGoal(); } + + /*! + * @brief Given a pointer to a Goal instance, sets the appropriate fields + * from the provided XML node. + * + * @param goal A pointer to the goal whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Goal * goal, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "x" float attribute. + */ + size_t _xID; + + /*! + * @brief The identifier for the "y" float attribute. + */ + size_t _yID; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __GOAL_POINT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/State.cpp b/src/Menge/MengeCore/BFSM/State.cpp new file mode 100644 index 00000000..01df8c2d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/State.cpp @@ -0,0 +1,241 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "State.h" +#include "BaseAgent.h" +#include "FSM.h" +#include "GoalSelectors/GoalSelector.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of State + ///////////////////////////////////////////////////////////////////// + + size_t State::COUNT = 0; + Vector2 State::NULL_POINT; + + ///////////////////////////////////////////////////////////////////// + + State::State( const std::string & name ): _velComponent(0x0), transitions_(),actions_(), _final(false), _goalSelector(0x0), _goals(), _name(name) { + _id = COUNT++; + } + + ///////////////////////////////////////////////////////////////////// + + State::~State() { + for ( size_t i = 0; i < actions_.size(); ++i ) { + actions_[i]->destroy(); + } + _velComponent->destroy(); + if ( _goalSelector ) { + _goalSelector->destroy(); + _goalSelector = 0x0; + } + } + + ///////////////////////////////////////////////////////////////////// + + void State::getTasks( FSM * fsm ) { + fsm->addTask( _goalSelector->getTask() ); + + for ( size_t i = 0; i < actions_.size(); ++i ) { + fsm->addTask( actions_[i]->getTask() ); + } + + fsm->addTask( _velComponent->getTask() ); + + for ( size_t i = 0; i < transitions_.size(); ++i ) { + transitions_[i]->getTasks( fsm ); + } + + for ( size_t i = 0; i < velModifiers_.size(); ++i ) { + //velModifiers_[i]->getTask( fsm ); + fsm->addTask(velModifiers_[i]->getTask()); + } + } + + ///////////////////////////////////////////////////////////////////// + + //change this to accept a velPref reference + void State::getPrefVelocity( Agents::BaseAgent * agent, Agents::PrefVelocity &velocity ) { + Goal * goal; + _goalLock.lockRead(); + goal = _goals[ agent->_id ]; + _goalLock.releaseRead(); + + //this needs to get changed. Create a copy of the VelPref. Pass that in, and then pass it back + + _velComponent->setPrefVelocity( agent, goal, velocity); + + //apply my velocity modifiers now + std::vector< VelModifier * >::iterator vItr = velModifiers_.begin(); + for ( ; vItr != velModifiers_.end(); ++vItr ) { + (*vItr)->adaptPrefVelocity(agent, velocity); + } + } + + ///////////////////////////////////////////////////////////////////// + + State * State::testTransitions( Agents::BaseAgent * agent ) { + std::set< State * > visited; + State * newNode = testTransitions( agent, visited ); + return newNode; + } + + ///////////////////////////////////////////////////////////////////// + + State * State::testTransitions( Agents::BaseAgent * agent, std::set< State * > &visited ) { + #ifdef _DEBUG + _goalLock.lockRead(); + assert( _goals.count( agent->_id ) == 1 && "Testing transitions for an agent without a goal!" ); + _goalLock.releaseRead(); + #endif + + if ( visited.find( this ) != visited.end() ) return 0x0; + visited.insert( this ); + + _goalLock.lockRead(); + Goal * goal = _goals[ agent->_id ]; + _goalLock.releaseRead(); + + for ( size_t i = 0; i < transitions_.size(); ++i ) { + State * next = transitions_[i]->test( agent, goal ); + if ( next ) { + leave( agent ); // a transition has come back true, leaving this state + next->enter( agent ); + State * test = next->testTransitions( agent, visited ); + if ( test ) { + return test; + } else { + return next; + } + } + } + return 0x0; + } + + ///////////////////////////////////////////////////////////////////// + + void State::enter( Agents::BaseAgent * agent ) { + for ( size_t i = 0; i < actions_.size(); ++i ) { + actions_[i]->onEnter( agent ); + } + + Goal * goal = 0x0; + try { + goal = _goalSelector->assignGoal( agent ); + } catch ( GoalSelectorException ) { + logger << Logger::ERR_MSG << "State " << _name << " was unable to assign a goal to agent " << agent->_id << "."; + throw StateException(); + } + + _goalLock.lockWrite(); + _goals[ agent->_id ] = goal; + _goalLock.releaseWrite(); + + _velComponent->onEnter( agent ); + for ( size_t i = 0; i < transitions_.size(); ++i ) { + transitions_[i]->onEnter( agent ); + } + + //velmodifiers + for ( size_t i = 0; i < velModifiers_.size(); ++i ) { + velModifiers_[i]->onEnter( agent ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void State::leave( Agents::BaseAgent * agent ) { + _goalSelector->freeGoal( agent, _goals[ agent->_id ] ); + + _goalLock.lockWrite(); + _goals.erase( agent->_id ); + _goalLock.releaseWrite(); + + for ( size_t i = 0; i < actions_.size(); ++i ) { + actions_[i]->onLeave( agent ); + } + _velComponent->onExit( agent ); + for ( size_t i = 0; i < transitions_.size(); ++i ) { + transitions_[i]->onLeave( agent ); + } + + for ( size_t i = 0; i < velModifiers_.size(); ++i ) { + velModifiers_[i]->onLeave( agent ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t State::getPopulation() const { + // It is assumed that every agent actually in the state has a + // representation in _goals. + // This works because goal persistence is stored in the goal + // selector. + _goalLock.lockRead(); + size_t size = _goals.size(); + _goalLock.releaseRead(); + return size; + } + + ///////////////////////////////////////////////////////////////////// + + void State::setGoalSelector( GoalSelector * selector ) { + if ( _goalSelector != 0x0 ) { + logger << Logger::ERR_MSG << "The state \"" << _name << "\" has been assigned multiple goal selectors."; + throw GoalSelectorException(); + } + _goalSelector = selector; + } + + ///////////////////////////////////////////////////////////////////// + + void State::clearGoalSelector() { + if ( _goalSelector ) { + _goalSelector->destroy(); + _goalSelector = 0x0; + } + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/State.h b/src/Menge/MengeCore/BFSM/State.h new file mode 100644 index 00000000..26cfad8b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/State.h @@ -0,0 +1,357 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file State.h + * @brief The definition of the BFSM state nodes. + */ + +#ifndef __FSMNODE_H__ +#define __FSMNODE_H__ + +#include +#include +#include "Transitions/Transition.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityModifiers/VelModifier.h" +#include "Actions/Action.h" +#include "FSMEnumeration.h" +#include "PrefVelocity.h" +#include "ReadersWriterLock.h" +#include "MengeException.h" +#include + +namespace Menge { + + namespace BFSM { + + // forward declaration + class StateContext; + class GoalSelector; + class Goal; + class FSM; + + /*! + * @brief Exception class for BFSM states. + */ + class MENGE_API StateException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + StateException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + StateException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the state has an error which cannot be + * recovered from. + */ + class StateFatalException : public StateException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + StateFatalException() : MengeException(), StateException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + StateFatalException( const std::string & s ): MengeException(s), StateException(), MengeFatalException() {} + }; + + /////////////////////////////////////////////////////////////////// + + /*! + * @brief The basic state of the behavior finite state machine. + * + * A state node in the finite state machine for determining "behaviors". + * The state requires a velocity component to determine how the preferred + * velocity is computed (see VelComponent). + * State's can also include actions, taken on an agent when it leaves the + * state and an optional corresponding action upon leaving the state (see Action). + * Agents leave the state based on transitions (see Transition). + * + * State's can be marked as "final". Agents *can* transition out of final + * states. However, in any given time step, when all agents are in final states + * the simulation stops. + */ + class State { + /*! + * @brief Counter on total states created. + * Gives each state a globally unique identifier. + */ + static size_t COUNT; + + /*! + * @brief A zero-vector to use with goal positions. + */ + static Vector2 NULL_POINT; + + public: + /*! + * @brief Constructor. + * + * @param name The name of this state. + */ + State( const std::string & name ); + + /*! + * @brief Destructor. + */ + ~State(); + + /*! + * @brief Gets the tasks for all of the state's FSM elements. + * + * @param fsm A pointer to the fsm. Tasks are fed to the fsm. + */ + void getTasks( FSM * fsm ); + + /*! + * @brief Modifies the input preferred velocity to reflect a velocity for the agent specified + * + * @param agent The agent for which a preferred velocity is computed. + * @param velocity The preferred velocity object (by reference) to modify reflecting the agent's new velocity + */ + void getPrefVelocity( Agents::BaseAgent * agent, Agents::PrefVelocity &velocity ); + + /*! + * @brief Set whether the state is final or not. + * + * @param isFinal If true, the state is set to be final, if false, not. + */ + inline void setFinal( bool isFinal ) { _final = isFinal; } + + /*! + * @brief Reports if the state is final or not. + * + * @returns True if the state is a final state, false otherwise. + */ + inline bool getFinal() const { return _final; } + + /*! + * @brief Test the transitions out of this state for the given agent. + * + * The transitions will be tested in priority order. The first transition which + * is found to be active will be taken. + * + * @param agent The agent to test w.r.t. the transitions. + * @returns A pointer to the next state if a transition is active, otherwise, + * it returns NULL, meaning the agent remains in this state. + */ + State * testTransitions( Agents::BaseAgent * agent ); + + /*! + * @brief Automatically called when an agent enters the state. + * + * @param agent The agent who entered the state. + */ + virtual void enter( Agents::BaseAgent * agent ); + + /*! + * @brief Automatically called when an agent leaves the state. + * + * @param agent The agent who left the state. + */ + virtual void leave( Agents::BaseAgent * agent ); + + /*! + * @brief Add a transition to the state. + * + * It is assumed that the transition is already correctly connected to + * the states as is required (the "to" and "from" states). The order + * the transitions are added inherently defines their priority. + * + * @param t The transition to add. + */ + void addTransition( Transition * t ) { transitions_.push_back( t ); } + + /*! + * @brief Sets the velocity component to the state. + * + * Once this is called, the State takes ownership of the velocity component + * and the caller should not destroy it. + * + * @param vc The velocity component to set. + */ + void setVelComponent( VelComponent * vc ) { _velComponent = vc; } + + /*! + * @brief Add an action to the state. + * + * @param a The action to add. + */ + void addAction( Action * a ) { actions_.push_back( a ); } + + /*! + * @brief Add an velocity modifier to the state + * + * @param v The modifier to add + */ + void addVelModifier( VelModifier * v ) { velModifiers_.push_back( v ); } + + /*! + * @brief Returns the *globally* unique state identifier. + * + * The identifier is unique w.r.t. all other states (although the same identifier + * may be used for other entities in their own contexts). + * + * @returns The state's identifier. + */ + size_t getID() const { return _id; } + + /*! + * @brief Returns the name of the state. + * + * @returns The state's name. + */ + std::string getName() const { return _name; } + + /*! + * @brief Returns the number of agents in this state. + * + * @returns The number of agents in this state. + */ + size_t getPopulation() const; + + /*! + * @brief Sets the goal selector for the state + * + * Once the goal selector is assigned to the state, the state takes ownership of + * the memory and is responsible for freeing it. + * + * @param selector A pointer to the goal selector. + */ + void setGoalSelector( GoalSelector * selector ); + + /*! + * @brief Returns a pointer to the goal selector. + * + * @returns Pointer to the state's goal selector. + */ + GoalSelector * getGoalSelector() { return _goalSelector; } + + /*! + * @brief Clears the state's current goal selector. + */ + void clearGoalSelector(); + + friend class StateContext; + + + protected: + /*! + * @brief Test the transitions out of this state, tracking cycles. + * + * The transitions will be tested in priority order. The first transition which + * is found to be active will be taken. + * + * @param agent The agent to test w.r.t. the transitions. + * @param visited The set of states visited during transition testing. + * Used to prevent cycles. + * @returns A pointer to the next state if a transition is active, otherwise, + * it returns NULL, meaning the agent remains in this state. + */ + State * testTransitions( Agents::BaseAgent * agent, std::set< State * > &visited ); + + /*! + * @brief The single velocity component associated with this state. + */ + VelComponent * _velComponent; + + /*! + * @brief A priority-ordered list of transitions to determine if the state changes. + * The order of the transitions in the implicitly defines the testing priority. + */ + std::vector< Transition * > transitions_; + + /*! + * @brief A priority-ordered list of velocity modifiers to determine if the state changes. + * The order of the modifierss in the implicitly defines the testing priority. + */ + std::vector< VelModifier * > velModifiers_; + + /*! + * @brief Actions to take upon entering and leaving the state. + */ + std::vector< Action * > actions_; + + /*! + * @brief Determines if the state is a final state (true), or not (false). + */ + bool _final; + + /*! + * @brief The goal selector for this state. + */ + GoalSelector * _goalSelector; + + /*! + * @brief A mapping from agent id to its per-agent goal. + */ + HASH_MAP< size_t, Goal * > _goals; + + /*! + * @brief The name of the state. + */ + std::string _name; + + /*! + * @brief The globally unique id of state + */ + size_t _id; + + /*! + * @brief The lock for accessing the goals. + */ + ReadersWriterLock _goalLock; + }; + } // namespace BFSM +} // namespace Menge + +#endif //__FSMNODE_H__ diff --git a/src/Menge/MengeCore/BFSM/StateContext.cpp b/src/Menge/MengeCore/BFSM/StateContext.cpp new file mode 100644 index 00000000..a8d68666 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/StateContext.cpp @@ -0,0 +1,135 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateContext.h" +#include "BaseAgent.h" +#include "State.h" +#include "Goals/Goal.h" +#include +#include + +#ifdef _WIN32 +#undef max +#endif + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of StateContext + ///////////////////////////////////////////////////////////////////// + + size_t StateContext::NO_ACTIVE_ID = std::numeric_limits< size_t >::max(); + + ///////////////////////////////////////////////////////////////////// + + StateContext::StateContext( State * state ):_state(state) { + _vcContext = _state->_velComponent->getContext(); + _activeTransition = _state->transitions_.size() == 1 ? 0 : NO_ACTIVE_ID; + } + + ///////////////////////////////////////////////////////////////////// + + StateContext::~StateContext() { + } + + ///////////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult StateContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result( false, false ); + + result = _vcContext->handleKeyboard( e ); + if ( ! result.isHandled() && _activeTransition != NO_ACTIVE_ID ) { + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + // TODO: Once I have transition contexts + //if ( e.type == SDL_KEYDOWN ) { + // if ( !hasCtrl && !hasAlt && hasShift ) { + // if ( e.key.keysym.sym == SDLK_UP ) { + // ++_activeTransition; + // if ( _activeTransition >= _transContexts.size() ) { + // _activeTransition = NO_ACTIVE_ID; + // } + // result.set( true, true ); + // } + // } + //} + } + return result; + } + + ///////////////////////////////////////////////////////////////////// + + std::string StateContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "State: " << _state->getName(); + std::string childIndent = indent + " "; + + ss << "\n" << childIndent << "Display (Ctrl-V)elocity Component"; + ss << "\n" << _vcContext->getUIText( childIndent + " " ); + + #if 1 + ss << "\n" << childIndent << "Transitions not yet supported"; + #else + if ( _activeTransition == NO_ACTIVE_ID ) { + ss << "\n" << childIndent << _state->transitions_.size() << " transitions (Alt + up arrow to select)"; + } else { + ss << "\n" << childIndent << "Display (Alt-T)ransition"; + ss << "\n" << childIndent << " Transition w/o context selected"; + } + #endif + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void StateContext::draw3DGL( const Agents::BaseAgent * agt, bool drawVC, bool drawTrans ) { + Goal * goal = _state->_goals[ agt->_id ]; + goal->drawGL(); + if ( drawVC ) { + _vcContext->draw3DGL( agt, goal ); + } + if ( drawTrans && _activeTransition != NO_ACTIVE_ID ) { + } + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/StateContext.h b/src/Menge/MengeCore/BFSM/StateContext.h new file mode 100644 index 00000000..bb5b8481 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/StateContext.h @@ -0,0 +1,154 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateContext.h + * @brief The definition of a basic UI context for finite + * state machine *states*. + */ + +#ifndef __STATE_CONTEXT_H__ +#define __STATE_CONTEXT_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Context.h" +#include "VelocityComponents/VelCompContext.h" + +namespace Menge { + + // forward declaration + namespace BFSM { + class StateContext; + } + + /*! + * @brief A map from state ids to statecontexts to facilitate lookups for a visualized agent + */ + typedef HASH_MAP< size_t, BFSM::StateContext * > StateContextMap; + + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + + // Forward declarations + class State; + + /*! + * @brief Base context for finite state machine states. + * + * This differs from the standard scene graph context by being + * dependent on an input agent. + */ + class StateContext : public SceneGraph::Context { + public: + /*! + * @brief Constructor. + * + * @param state A pointer to the underlying fsm state. + * The context will *not* delete the state. + */ + StateContext( State * state ); + + /*! + * @brief Destructor. + */ + virtual ~StateContext(); + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing state information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param drawVC Draw the velocity component + * @param drawTrans Draw the transition + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, bool drawVC, bool drawTrans ); + + protected: + /*! + * @brief The underlying finite state machine state. + */ + State * _state; + + /*! + * @brief The value used to indicate that no id is selected. + * + * Used in conjunction with the _activeVC and _activeTransition + */ + static size_t NO_ACTIVE_ID; + + /*! + * @brief The velocity component context for this state. + */ + VelCompContext * _vcContext; + + /*! + * @brief The id of the "active" transition. + * + * This is the index of the transition which is currently being + * visualized in the context. + */ + size_t _activeTransition; + + }; + } // namespace BFSM +} // namespace Menge +#endif // __STATE_CONTEXT_H__ diff --git a/src/Menge/MengeCore/BFSM/StateDescrip.cpp b/src/Menge/MengeCore/BFSM/StateDescrip.cpp new file mode 100644 index 00000000..6f4e63a2 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/StateDescrip.cpp @@ -0,0 +1,164 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "StateDescrip.h" +#include "tinyxml.h" +#include "Actions/Action.h" +#include "GoalSelectors/GoalSelector.h" +#include "State.h" +#include "os.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of StateDescrip + ///////////////////////////////////////////////////////////////////// + + StateDescrip::StateDescrip( const std::string & name, bool isFinal ): _name(name), _isFinal(isFinal), _goalSelector(0x0), _velComponent(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + StateDescrip::~StateDescrip() { + if ( _velComponent ) _velComponent->destroy(); + + std::list< Action * >::const_iterator aItr = _actions.begin(); + for ( ; aItr != _actions.end(); ++aItr ) { + (*aItr)->destroy(); + } + + if ( _goalSelector ) { + _goalSelector->destroy(); + } + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const StateDescrip & state ) { + out << "\t\tState( " << state._name << " ), "; + if ( state._isFinal ) { + out << " -- FINAL state"; + } + out << "\nVelocity component streaming not supported yet."; + // todo: out << "\n" << (*state->_velComponent); + + out << "\nAction streaming not supported yet."; + // TODO: realize this + //std::list< Action * >::const_iterator aItr = state._actions.begin(); + //for ( ; aItr != state._actions.end(); ++aItr ) { + // out << "\n" << (**aItr); + //} + return out; + } + + ///////////////////////////////////////////////////////////////////// + + bool parseState( TiXmlElement * node, const std::string & behaveFldr, std::list< StateDescrip * > & states ) { + StateDescrip * s = 0x0; + const char * cName = node->Attribute( "name" ); + if ( cName == 0x0 ) { + logger << Logger::ERR_MSG << "State tags require a name\n"; + return false; + } + std::string name( cName ); + if ( name == "" ) { + logger << Logger::ERR_MSG << "Undefined state name!\n"; + return false; + } + + int i; + bool isFinal = false; + if ( ! node->Attribute( "final", &i ) ) { + logger << Logger::ERR_MSG << "State must specify whether it is final or not\n"; + return false; + } else { + isFinal = i != 0; + } + + s = new StateDescrip( name, isFinal ); + + for ( TiXmlElement * gchild = node->FirstChildElement(); gchild; gchild = gchild->NextSiblingElement() ) { + if ( gchild->ValueStr() == "Action" ) { + Action * action = parseAction( gchild, behaveFldr ); + if ( action == 0x0 ) { + delete s; + return false; + } + s->_actions.push_back( action ); + } else if ( gchild->ValueStr() == "VelComponent" ) { + if ( s->_velComponent != 0x0 ) { + logger << Logger::ERR_MSG << "Multiple velocity components defined for the state (" << s->_name << ") on line " << gchild->Row() << ". Only one VelComponent can be defined per state."; + delete s; + return false; + } + s->_velComponent = parseVelComponent( gchild, behaveFldr ); + if ( s->_velComponent == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate a velocity component for state " << s->_name << ". Simulation cannot proceed."; + delete s; + return false; + } + } else if ( gchild->ValueStr() == "GoalSelector" ) { + s->_goalSelector = parseGoalSelector( gchild, behaveFldr ); + if ( s->_goalSelector == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to instantiate a goal selector for state " << s->_name << ". Simulation cannot proceed."; + // This doesn't result in a default -- this is an error. A Goal selector MUST be specified. + delete s; + return false; + } + } else if ( gchild->ValueStr() == "VelModifier" ) { + VelModifier *vel = parseVelModifier( gchild, behaveFldr ); + if ( vel == 0x0 ) { + delete s; + return false; + } else { + s->_velModifiers.push_back(vel); + } + } else { + logger << Logger::ERR_MSG << "State contains an improper child element: " << gchild->ValueStr() << "."; + return false; + } + } + states.push_back( s ); + + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/StateDescrip.h b/src/Menge/MengeCore/BFSM/StateDescrip.h new file mode 100644 index 00000000..35682534 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/StateDescrip.h @@ -0,0 +1,140 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file StateDescrip.h + * @brief The state (and state goal) specification in the behavior configuration file. + */ + +#ifndef __STATE_DESCRIP_H__ +#define __STATE_DESCRIP_H__ + +#include "fsmCommon.h" +#include +#include + + +// forward declarations +class TiXmlElement; + +namespace Menge { + + namespace BFSM { + // forward declarations + class Action; + class GoalSelector; + class VelComponent; + class VelModifier; + + + //////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The description of a state (see State). + */ + class StateDescrip { + public: + /*! + * @brief Constructor. + * + * @param name The name of the state. + * @param isFinal Determines if this state is a final state (true) or not (false). + */ + StateDescrip( const std::string & name, bool isFinal ); + + /*! + * @brief Destructor + */ + ~StateDescrip(); + + /*! + * @brief Friend operator for printing the state description to an output stream. + * + * @param out The output stream. + * @param state A state description to write to the stream. + * @returns The provided output stream. + */ + friend Logger & operator<<( Logger & out, const StateDescrip & state ); + + /*! + * @brief The name of the state. + */ + std::string _name; + + /*! + * @brief Dictates whether this state is considered a "final" state (true) or not (false). + */ + bool _isFinal; + + /*! + * @brief The description of the goal selector used for this state. + */ + GoalSelector * _goalSelector; + + /*! + * @brief The velocity component for this state. + */ + VelComponent * _velComponent; + + /*! + * @brief The set of actions for this state. + */ + std::list< Action * > _actions; + + /*! + * @brief The set of actions for this state. + */ + std::vector< VelModifier * > _velModifiers; //TODO: list or vector? + }; + + /*! + * @brief Parses a TinyXML element containing a state description + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @param states List of state descriptions. The new state description + * is appended to the end of this liest. + * @returns A boolean reporting succes (true) or failure (false). + */ + bool parseState( TiXmlElement * node, const std::string & behaveFldr, std::list< StateDescrip * > & states ); + + } // namespace BFSM +} // namespace Menge + +#endif // __STATE_DESCRIP_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.cpp b/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.cpp new file mode 100644 index 00000000..303add86 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.cpp @@ -0,0 +1,101 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshLocalizerTask.h" +#include "FSM.h" +#include "NavMeshLocalizer.h" +#include "SimulatorInterface.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshLocalizerTask + ///////////////////////////////////////////////////////////////////// + + NavMeshLocalizerTask::NavMeshLocalizerTask( const std::string & navMeshName, bool usePlanner ): Task() { + _localizer = loadNavMeshLocalizer( navMeshName, usePlanner ); + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocalizerTask::doWork( const FSM * fsm ) throw( TaskException ) { + const Agents::SimulatorInterface * sim = fsm->getSimulator(); + int agtCount = (int)sim->getNumAgents(); + + size_t exceptionCount = 0; + #pragma omp parallel for reduction(+:exceptionCount) + for ( int a = 0; a < agtCount; ++a ) { + try { + const Agents::BaseAgent * agt = sim->getAgent( a ); + _localizer->updateLocation( agt ); + } catch ( Menge::MengeException & e ){ + logger << Logger::ERR_MSG << e.what() << "\n"; + ++exceptionCount; + } catch ( std::exception & e ) { + logger << Logger::ERR_MSG << "Unanticipated system exception: " << e.what() << "."; + ++exceptionCount; + } + } + if ( exceptionCount > 0 ) { + throw TaskFatalException(); + } + } + ///////////////////////////////////////////////////////////////////// + + std::string NavMeshLocalizerTask::toString() const { + // TODO: include the name of the navigation mesh + return "Navigation Mesh Localizer Task"; + } + + ///////////////////////////////////////////////////////////////////// + + bool NavMeshLocalizerTask::isEquivalent( const Task * task ) const { + const NavMeshLocalizerTask * other = dynamic_cast< const NavMeshLocalizerTask * >( task ); + if ( other == 0x0 ) { + return false; + } else { + return _localizer == other->_localizer; + } + } + + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.h b/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.h new file mode 100644 index 00000000..731735ea --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/NavMeshLocalizerTask.h @@ -0,0 +1,117 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __NAV_MESH_LOCALIZER_TASK_H__ +#define __NAV_MESH_LOCALIZER_TASK_H__ + +/*! + * @file NavMeshLocalizerTask.h + * @brief A task based on the NavMeshLocalizer so that it updates + * its tracked agent positions at every FSM time step. + */ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Resource.h" +#include "Task.h" + +namespace Menge { + + // forward declaration + class NavMeshLocalizer; + + /*! + * @brief forward declaration. See NavMeshLocalizer for more details + */ + typedef ResourcePtr< NavMeshLocalizer > NavMeshLocalizerPtr; + + namespace BFSM { + /*! + * @brief Sub-class of NavMeshLocalizer that can be run as an FSM task + */ + class MENGE_API NavMeshLocalizerTask : public Task { + public: + /*! + * @brief Constructor from a localizer. + * + * @param navMeshName The name of the navigation mesh which the + * task depends on. + * @param usePlanner Indicates if the localizer should use a planner + * (true) or not (false). + */ + NavMeshLocalizerTask( const std::string & navMeshName, bool usePlanner ); + + /*! + * @brief The work performed by the task. + * + * @param fsm The finite state machine for the task to operate on. + * @throws A TaskException if there was some non-fatal error + * in execution. It should be logged. + * @throws A TaskFatalException if there is a fatal error that + * should arrest execution of the simulation. + */ + virtual void doWork( const FSM * fsm ) throw( TaskException ); + + /*! + * @brief String representation of the task + * + * @returns A string containing task information. + */ + virtual std::string toString() const; + + /*! + * @brief Reports if this task is "equivalent" to the given task. + * This makes it possible for a task to be redundantly added + * to the fsm without fear of duplication as the equivalent + * duplicates will be culled. + * + * @param task The task to test against this one. + * @returns A boolean reporting if the two tasks are equivalent (true) + * or unique (false). + */ + virtual bool isEquivalent( const Task * task ) const; + + protected: + /*! + * @brief The localizer used by this task. + */ + NavMeshLocalizerPtr _localizer; + }; + } // namespace BFSM +} // namespace Menge +#endif // __NAV_MESH_LOCALIZER_TASK_H__ diff --git a/src/Menge/MengeCore/BFSM/Tasks/Task.cpp b/src/Menge/MengeCore/BFSM/Tasks/Task.cpp new file mode 100644 index 00000000..aa4fc79a --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/Task.cpp @@ -0,0 +1,54 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Task.h" +#include "TaskDatabase.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of parsing function + ///////////////////////////////////////////////////////////////////// + + Task * parseTask( TiXmlElement * node, const std::string & behaveFldr ) { + return TaskDB::getInstance( node, behaveFldr ); + } + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/Tasks/Task.h b/src/Menge/MengeCore/BFSM/Tasks/Task.h new file mode 100644 index 00000000..4afd7af4 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/Task.h @@ -0,0 +1,165 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __TASK_H__ +#define __TASK_H__ + +/*! + * @file Task.h + * @brief Defines the interface for behavior FSM tasks. + * actions that need to be taken at each time step. + */ +#include "fsmCommon.h" +#include "Element.h" +#include "MengeException.h" + +#include + +// forward declaration +class TiXmlElement; + +namespace Menge { + + namespace BFSM { + + // FORWARD DECLARATIONS + class FSM; + + /*! + * @brief Exception thrown when a task fails at doing its work. + * These exceptions can be logged but should not arrest + * execution of the simulation. + */ + class TaskException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + TaskException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + TaskException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the task has an error which cannot be + * recovered from. + */ + class TaskFatalException : public TaskException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + TaskFatalException() : MengeException(), TaskException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + TaskFatalException( const std::string & s ): MengeException(s), TaskException(), MengeFatalException() {} + }; + + /*! + * @brief Interface for basic FSM task. + * + * Tasks must implement three functions: doWork, toString, and + * isEquivalent. Tasks' doWork functions are evaluated at the + * beginning of each FSM evaluation per time step. + */ + class MENGE_API Task : public Element { + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~Task(){} + + public: + /*! + * @brief The work performed by the task. + * + * @param fsm The behavior finite state machine on which the task + * is performed. + * + * @throws A TaskException if there was some non-fatal error + * in execution. It should be logged. + * @throws A TaskFatalException if there is a fatal error that + * should arrest execution of the simulation. + */ + virtual void doWork( const FSM * fsm ) throw( TaskException ) = 0; + + /*! + * @brief String representation of the task + * + * TODO: Determine when this is used. + * + * @returns A string containing task information. + */ + virtual std::string toString() const = 0; + + /*! + * @brief Reports if this task is "equivalent" to the given task. + * + * This makes it possible for a task to be redundantly added + * to the fsm without fear of duplication as the equivalent + * duplicates will be culled. + * + * @param task The task to test against this one. + * @returns A boolean reporting if the two tasks are equivalent (true) + * or unique (false). + */ + virtual bool isEquivalent( const Task * task ) const = 0; + }; + + /*! + * @brief Parses a TinyXML element containing a task specification + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new task instance. + */ + Task * parseTask( TiXmlElement * node, const std::string & behaveFldr ); + } // namespace BFSM +} // namespace Menge +#endif // __TASK_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.cpp b/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.cpp new file mode 100644 index 00000000..43745156 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.cpp @@ -0,0 +1,55 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "TaskDatabase.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::TaskFactory, BFSM::Task >::getElementName() { return "task"; } + + template <> + void ElementDB< BFSM::TaskFactory, BFSM::Task >::addBuiltins() { + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.h b/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.h new file mode 100644 index 00000000..6d29a5f9 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/TaskDatabase.h @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TaskDatabase.h + * @brief Central database for querying available behavior actions. + * + * For tasks to be used in the finite state machine, they must register + * themselves into the TaskDatabase. This is done via the PluginEngine. + */ + +#ifndef __TASK_DATABASE_H__ +#define __TASK_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Tasks/TaskFactory.h" +#include "Tasks/Task.h" + +namespace Menge { + + namespace BFSM { + + /*! + * @brief The database of registered task implementations. + */ + typedef ElementDB< TaskFactory, Task > TaskDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + /*! + * @brief Explicit specialization of addBuiltins for the Task Database + */ + template<> void ElementDB< BFSM::TaskFactory, BFSM::Task >::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the Task Database + */ + template<> std::string ElementDB< BFSM::TaskFactory, BFSM::Task >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge +#endif // __TASK_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/Tasks/TaskFactory.h b/src/Menge/MengeCore/BFSM/Tasks/TaskFactory.h new file mode 100644 index 00000000..a1fcfc58 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Tasks/TaskFactory.h @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TaskFactory.h + * @brief The factory for parsing xml data and instantiating + * tasks. + */ + +#ifndef __TASK_FACTORY_H__ +#define __TASK_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "Tasks/Task.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a task + * and instantiating particular instances. + */ + class MENGE_API TaskFactory : public ElementFactory< Task > { + }; + } // namespace BFSM +} // namespace Menge +#endif // __TASK_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondAuto.h b/src/Menge/MengeCore/BFSM/Transitions/CondAuto.h new file mode 100644 index 00000000..1716503b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondAuto.h @@ -0,0 +1,133 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CondAuto.h + * @brief The definition of the automatic condition. + */ + +#ifndef __COND_AUTO_H__ +#define __COND_AUTO_H__ + +#include "CoreConfig.h" +#include "Condition.h" +#include "ConditionFactory.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The definition of the "auto" condition. + * + * The auto condition always evaluates to true. It can be used + * to automatically progress from one state to another -- or as a default + * case when multiple transitions are possible and the transition with + * the auto condition should be taken when no other transition proved + * to be valid. + */ + class MENGE_API AutoCondition : public Condition { + public: + /*! + * @brief The AutoCondition is always met -- it is a tautology. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { return true; } + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy() { return new AutoCondition(); } + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the AutoCondition + */ + class MENGE_API AutoCondFactory : public ConditionFactory { + public: + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "auto"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The tautological condition. It always evaluates to true. "\ + "If tested, the transition will be active."; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Condition class. + */ + virtual Condition * instance() const { return new AutoCondition(); } + }; + + } // namespace BFSM +} // namespace Menge +#endif // __COND_AUTO_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.cpp b/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.cpp new file mode 100644 index 00000000..71cf67bb --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.cpp @@ -0,0 +1,254 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "CondBoolean.h" +#include "ConditionDatabase.h" +#include "Logger.h" +#include "BaseAgent.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of Bool2Condition + /////////////////////////////////////////////////////////////////////////// + + Bool2Condition::Bool2Condition(): Condition(), _op1(0x0), _op2(0x0) { + } + + /////////////////////////////////////////////////////////////////////////// + + Bool2Condition::Bool2Condition( const Bool2Condition & cond ) { + _op1 = cond._op1->copy(); + _op2 = cond._op2->copy(); + } + + /////////////////////////////////////////////////////////////////////////// + + Bool2Condition::~Bool2Condition() { + if ( _op1 ) _op1->destroy(); + if ( _op2 ) _op2->destroy(); + } + + /////////////////////////////////////////////////////////////////////////// + + void Bool2Condition::onEnter( Agents::BaseAgent * agent ) { + _op1->onEnter( agent ); + _op2->onEnter( agent ); + } + + /////////////////////////////////////////////////////////////////////////// + + void Bool2Condition::onLeave( Agents::BaseAgent * agent ) { + _op1->onLeave( agent ); + _op2->onLeave( agent ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of Bool2CondFactory + /////////////////////////////////////////////////////////////////////////// + + bool Bool2CondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + Bool2Condition * bCond = dynamic_cast< Bool2Condition * >( condition ); + assert( bCond != 0x0 && "Trying to set the properties of a binary boolean condition on an incompatible object" ); + + if ( !ConditionFactory::setFromXML( bCond, node, behaveFldr ) ) return false; + + // There should be two xml tags for conditions. + int childCount = 0; + for ( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == "Condition" ) { + Condition * condition = ConditionDB::getInstance( child, behaveFldr ); + if ( condition == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to parse the child condition of a binary boolean condition on line " << child->Row() << ": " << child->ValueStr() << "."; + return false; + } + if ( childCount == 0 ) { + bCond->_op1 = condition; + ++childCount; + } else if ( childCount == 1 ) { + bCond->_op2 = condition; + ++childCount; + } else { + logger << Logger::ERR_MSG << "Too many child conditions for a binary boolean condition on line " << child->Row() << ": " << child->ValueStr() << "."; + return false; + } + } else { + logger << Logger::ERR_MSG << "Unrecognized child tag of a binary boolean condition on line " << child->Row() << ": " << child->ValueStr() << "."; + return false; + } + } + if ( childCount != 2 ) { + logger << Logger::ERR_MSG << "The binary boolean condition on line " << node->Row() << " requires TWO child conditions."; + return false; + } + return true; + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of AndCondition + /////////////////////////////////////////////////////////////////////////// + + AndCondition::AndCondition() : Bool2Condition() {} + + /////////////////////////////////////////////////////////////////////////// + + AndCondition::AndCondition( const AndCondition & cond ) : Bool2Condition(cond) { + } + + /////////////////////////////////////////////////////////////////////////// + + bool AndCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + // This relies on the compiler to only evaluate the second condition if the + // first is true. + return _op1->conditionMet( agent, goal ) && _op2->conditionMet( agent, goal ); + } + + /////////////////////////////////////////////////////////////////////////// + + Condition * AndCondition::copy() { + return new AndCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of OrCondition + /////////////////////////////////////////////////////////////////////////// + + OrCondition::OrCondition() : Bool2Condition() {} + + /////////////////////////////////////////////////////////////////////////// + + OrCondition::OrCondition( const OrCondition & cond ) : Bool2Condition(cond) { + } + + /////////////////////////////////////////////////////////////////////////// + + bool OrCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + // This relies on the compiler to only evaluate the second condition if the + // first is false. + return _op1->conditionMet( agent, goal ) || _op2->conditionMet( agent, goal ); + } + + /////////////////////////////////////////////////////////////////////////// + + Condition * OrCondition::copy() { + return new OrCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of NotCondition + /////////////////////////////////////////////////////////////////////////// + + NotCondition::NotCondition(): Condition(), _op(0x0) { + } + + /////////////////////////////////////////////////////////////////////////// + + NotCondition::NotCondition( const NotCondition & cond ) { + _op = cond._op->copy(); + } + + /////////////////////////////////////////////////////////////////////////// + + NotCondition::~NotCondition() { + if ( _op ) _op->destroy(); + } + + /////////////////////////////////////////////////////////////////////////// + + void NotCondition::onEnter( Agents::BaseAgent * agent ) { + _op->onEnter( agent ); + } + + /////////////////////////////////////////////////////////////////////////// + + void NotCondition::onLeave( Agents::BaseAgent * agent ) { + _op->onLeave( agent ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool NotCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + return ! _op->conditionMet( agent, goal ); + } + + /////////////////////////////////////////////////////////////////////////// + + Condition * NotCondition::copy() { + return new NotCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of NotCondFactory + /////////////////////////////////////////////////////////////////////////// + + bool NotCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + NotCondition * bCond = dynamic_cast< NotCondition * >( condition ); + assert( bCond != 0x0 && "Trying to set the properties of a NOT boolean condition on an incompatible object" ); + + if ( !ConditionFactory::setFromXML( bCond, node, behaveFldr ) ) return false; + + // There should be two xml tags for conditions. + TiXmlElement * child = node->FirstChildElement(); + if ( child == 0x0 ) { + logger << Logger::ERR_MSG << "The NOT condition on line " << node->Row() << " requires one child condition -- none provided."; + return false; + } else if ( child->NextSiblingElement() != 0x0 ) { + logger << Logger::ERR_MSG << "The NOT condition on line " << node->Row() << " has too many children elements - it should get a single condition element."; + return false; + } else { + if ( child->ValueStr() == "Condition" ) { + Condition * condition = ConditionDB::getInstance( child, behaveFldr ); + if ( condition == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to parse the child condition of the NOT condition on line " << child->Row() << ": " << child->ValueStr() << "."; + return false; + } else { + bCond->_op = condition; + } + } else { + logger << Logger::ERR_MSG << "The NOT condition on line " << node->Row() << " requires a single child condition. Found a " << child->ValueStr() << " on line " << child->Row() << "."; + return false; + } + } + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.h b/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.h new file mode 100644 index 00000000..a53de2e4 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondBoolean.h @@ -0,0 +1,451 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CondBoolean.h + * @brief Definition of boolean conditiosn for transition conditions. + */ + +#ifndef __COND_BOOLEAN_H__ +#define __COND_BOOLEAN_H__ + +#include "CoreConfig.h" +#include "Condition.h" +#include "ConditionFactory.h" + +namespace Menge { + + namespace BFSM { + + // forward declarations + class Bool2CondFactory; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The base class for binary boolean operand as a transition condition. + */ + class MENGE_API Bool2Condition : public Condition { + public: + /*! + * @brief Constructor. + */ + Bool2Condition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + Bool2Condition( const Bool2Condition & cond ); + + protected: + /*! + * @brief Protected destructor. + */ + virtual ~Bool2Condition(); + + public: + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ); + + friend class Bool2CondFactory; + + protected: + /*! + * @brief The first boolean operand. + */ + Condition * _op1; + + /*! + * @brief The second boolean operand. + */ + Condition * _op2; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the Bool2Condition + */ + class MENGE_API Bool2CondFactory : public ConditionFactory { + protected: + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A condition based on the boolean and of two conditions. + */ + class MENGE_API AndCondition : public Bool2Condition { + public: + /*! + * @brief Constructor. + */ + AndCondition(); + + /*! + * @brief Copy constructor. + * + * @param cond The condition to copy from. + */ + AndCondition( const AndCondition & cond ); + + /*! + * @brief The GoalCondition's condition is met when the + * agent is within a distance to the goal. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the AndCondition + */ + class MENGE_API AndCondFactory : public Bool2CondFactory { + public: + /*! + * @brief The name of the condition. + * + * The condition's name must be unique among all registered condition. + * Each condition factory must override this function. + * + * @returns A string containing the unique condition name. + */ + virtual const char * name() const { return "and"; } + + /*! + * @brief A description of the condition. + * + * Each condition factory must override this function. + * + * @returns A string containing the condition description. + */ + virtual const char * description() const { + return "The and condition. This condition depends on the evaluation of "\ + "two child conditions. If both are met, this condition is met."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new AndCondition(); } + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A condition based on the boolean OR of two conditions. + */ + class MENGE_API OrCondition : public Bool2Condition { + public: + /*! + * @brief Constructor. + */ + OrCondition(); + + /*! + * @brief Copy constructor. + * + * @param cond The condition to copy from. + */ + OrCondition( const OrCondition & cond ); + + /*! + * @brief The GoalCondition's condition is met when the + * agent is within a distance to the goal. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the OrCondition + */ + class MENGE_API OrCondFactory : public Bool2CondFactory { + public: + /*! + * @brief The name of the condition. + * + * The condition's name must be unique among all registered condition. + * Each condition factory must override this function. + * + * @returns A string containing the unique condition name. + */ + virtual const char * name() const { return "or"; } + + /*! + * @brief A description of the condition. + * + * Each condition factory must override this function. + * + * @returns A string containing the condition description. + */ + virtual const char * description() const { + return "The or condition. This condition depends on the evaluation of "\ + "two child conditions. If either are met, this condition is met."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new OrCondition(); } + }; + + /////////////////////////////////////////////////////////////////////////// + + // forward declaration + class NotCondFactory; + + /*! + * @brief A condition based on the boolean negation of a single condition. + */ + class MENGE_API NotCondition : public Condition { + public: + /*! + * @brief Constructor. + */ + NotCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + NotCondition( const NotCondition & cond ); + + protected: + /*! + * @brief Protected destructor. + */ + virtual ~NotCondition(); + + public: + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ); + + /*! + * @brief The GoalCondition's condition is met when the + * agent is within a distance to the goal. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + + friend class NotCondFactory; + + protected: + /*! + * @brief The boolean operand to negate. + */ + Condition * _op; + + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the NotCondition + */ + class MENGE_API NotCondFactory : public ConditionFactory { + public: + /*! + * @brief The name of the condition. + * + * The condition's name must be unique among all registered condition. + * Each condition factory must override this function. + * + * @returns A string containing the unique condition name. + */ + virtual const char * name() const { return "not"; } + + /*! + * @brief A description of the condition. + * + * Each condition factory must override this function. + * + * @returns A string containing the condition description. + */ + virtual const char * description() const { + return "The not condition. This condition depends on the evaluation of "\ + "a single child condition. This condition is met when the child is not "\ + " and vice versa."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new NotCondition(); } + + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __COND_BOOLEAN_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondGoal.cpp b/src/Menge/MengeCore/BFSM/Transitions/CondGoal.cpp new file mode 100644 index 00000000..c1556f82 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondGoal.cpp @@ -0,0 +1,95 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "CondGoal.h" +#include "BaseAgent.h" +#include "Logger.h" +#include "Goals/Goal.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of GoalCondition + /////////////////////////////////////////////////////////////////////////// + + GoalCondition::GoalCondition(): Condition(),_distSq(0.f) { + } + + /////////////////////////////////////////////////////////////////////////// + + GoalCondition::GoalCondition( const GoalCondition & cond ) : Condition(cond) { + _distSq = cond._distSq; + } + + /////////////////////////////////////////////////////////////////////////// + + bool GoalCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + float distSq = goal->squaredDistance( agent->_pos ); + return distSq <= _distSq; + } + + /////////////////////////////////////////////////////////////////////////// + + Condition * GoalCondition::copy() { + return new GoalCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of GoalCondFactory + ///////////////////////////////////////////////////////////////////// + + GoalCondFactory::GoalCondFactory() : ConditionFactory() { + _distanceID = _attrSet.addFloatAttribute( "distance", false /*required*/, 0.f /*default*/ ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool GoalCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + GoalCondition * gCond = dynamic_cast< GoalCondition * >( condition ); + assert( gCond != 0x0 && "Trying to set the properties of a goal condition on an incompatible object" ); + + if ( !ConditionFactory::setFromXML( gCond, node, behaveFldr ) ) return false; + + gCond->setMinDistance( _attrSet.getFloat( _distanceID ) ); + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondGoal.h b/src/Menge/MengeCore/BFSM/Transitions/CondGoal.h new file mode 100644 index 00000000..e9abf0f6 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondGoal.h @@ -0,0 +1,180 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CondGoal.h + * @brief The definition of the goal reached condition. + */ + +#ifndef __COND_GOAL_H__ +#define __COND_GOAL_H__ + +#include "CoreConfig.h" +#include "Condition.h" +#include "ConditionFactory.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A spatial transition based on individual goal positions. + */ + class MENGE_API GoalCondition : public Condition { + public: + /*! + * @brief Constructor. + */ + GoalCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + GoalCondition( const GoalCondition & cond ); + + /*! + * @brief The GoalCondition's condition is met when the + * agent is within a distance to the goal. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + + /*! + * @brief Set the minimum distance of approach. + * + * @param dist The minimum distance to the goal to consider the condition met. + */ + void setMinDistance( float dist ) { _distSq = dist * dist; } + + protected: + /*! + * @brief Minimum distance of approach (squared for efficiency). + */ + float _distSq; + }; + + /*! + * @brief The factory for creating the GoalCondition + */ + class MENGE_API GoalCondFactory : public ConditionFactory { + public: + /*! + * @brief Constructor. + */ + GoalCondFactory(); + + /*! + * @brief The name of the condition. + * + * The condition's name must be unique among all registered condition. + * Each condition factory must override this function. + * + * @returns A string containing the unique condition name. + */ + virtual const char * name() const { return "goal_reached"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The goal condition. It becomes active when an agent reaches "\ + "a user-specified distance to the goal."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new GoalCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "distance" float attribute. + */ + size_t _distanceID; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __COND_GOAL_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondSpace.cpp b/src/Menge/MengeCore/BFSM/Transitions/CondSpace.cpp new file mode 100644 index 00000000..fd0514e6 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondSpace.cpp @@ -0,0 +1,228 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "CondSpace.h" +#include "BaseAgent.h" +#include "Logger.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of SpaceCondition + /////////////////////////////////////////////////////////////////////////// + + SpaceCondition::SpaceCondition(): Condition(),_outsideActive(false) { + } + + /////////////////////////////////////////////////////////////////////////// + + SpaceCondition::SpaceCondition( const SpaceCondition & cond ):Condition(cond), _outsideActive(cond._outsideActive) { + } + + /////////////////////////////////////////////////////////////////////////// + + SpaceCondition::~SpaceCondition() { + } + + /////////////////////////////////////////////////////////////////////////// + + bool SpaceCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + bool inside = containsPoint( agent->_pos ); + return inside ^ _outsideActive; // the xor flips the shape's result as necessary + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of SpaceCondFactory + ///////////////////////////////////////////////////////////////////// + + SpaceCondFactory::SpaceCondFactory() : ConditionFactory() { + _insideID = _attrSet.addBoolAttribute( "inside", true /*required*/ ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool SpaceCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + SpaceCondition * sCond = dynamic_cast< SpaceCondition * >( condition ); + assert( sCond != 0x0 && "Trying to set the properties of a space condition on an incompatible object" ); + + if ( !ConditionFactory::setFromXML( condition, node, behaveFldr ) ) return false; + + sCond->_outsideActive = !_attrSet.getBool( _insideID ); + return true; + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of CircleCondition + ///////////////////////////////////////////////////////////////////// + + CircleCondition::CircleCondition():SpaceCondition(),CircleShape() { + } + + ///////////////////////////////////////////////////////////////////// + + CircleCondition::CircleCondition( const CircleCondition & cond ):SpaceCondition(cond),CircleShape() { + _center = cond._center; + _radSqd = cond._radSqd; + } + + ///////////////////////////////////////////////////////////////////// + + Condition * CircleCondition::copy() { + return new CircleCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of CircleCondFactory + ///////////////////////////////////////////////////////////////////// + + CircleCondFactory::CircleCondFactory() : SpaceCondFactory() { + _centerXID = _attrSet.addFloatAttribute( "center_x", true /*required*/ ); + _centerYID = _attrSet.addFloatAttribute( "center_y", true /*required*/ ); + _radiusID = _attrSet.addFloatAttribute( "radius", true /*required*/ ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool CircleCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + CircleCondition * cCond = dynamic_cast< CircleCondition * >( condition ); + assert( cCond != 0x0 && "Trying to set the properties of a circle condition on an incompatible object" ); + + if ( !SpaceCondFactory::setFromXML( cCond, node, behaveFldr ) ) return false; + + cCond->set( Vector2( _attrSet.getFloat( _centerXID ), _attrSet.getFloat( _centerYID ) ), + _attrSet.getFloat( _radiusID ) ); + return true; + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of AABBCondition + ///////////////////////////////////////////////////////////////////// + + AABBCondition::AABBCondition():SpaceCondition(),AABBShape() { + } + + ///////////////////////////////////////////////////////////////////// + + AABBCondition::AABBCondition( const AABBCondition & cond ):SpaceCondition(cond),AABBShape(cond._minPt,cond._maxPt) { + } + + ///////////////////////////////////////////////////////////////////// + + Condition * AABBCondition::copy() { + return new AABBCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of AABBCondFactory + ///////////////////////////////////////////////////////////////////// + + AABBCondFactory::AABBCondFactory() : SpaceCondFactory() { + _minXID = _attrSet.addFloatAttribute( "min_x", true /*required*/ ); + _minYID = _attrSet.addFloatAttribute( "min_y", true /*required*/ ); + _maxXID = _attrSet.addFloatAttribute( "max_x", true /*required*/ ); + _maxYID = _attrSet.addFloatAttribute( "max_y", true /*required*/ ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool AABBCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + AABBCondition * cond = dynamic_cast< AABBCondition * >( condition ); + assert( cond != 0x0 && "Trying to set the properties of a AABB condition on an incompatible object" ); + + if ( !SpaceCondFactory::setFromXML( cond, node, behaveFldr ) ) return false; + + cond->set( Vector2( _attrSet.getFloat( _minXID ), _attrSet.getFloat( _minYID ) ), + Vector2( _attrSet.getFloat( _maxXID ), _attrSet.getFloat( _maxYID ) ) + ); + return true; + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of OBBCondition + ///////////////////////////////////////////////////////////////////// + + OBBCondition::OBBCondition():SpaceCondition(),OBBShape() { + } + + ///////////////////////////////////////////////////////////////////// + + OBBCondition::OBBCondition( const OBBCondition & cond ):SpaceCondition(cond),OBBShape() { + _pivot = cond._pivot; + _size = cond._size; + _halfSize = cond._halfSize; + _cosTheta = cond._cosTheta; + _sinTheta = cond._sinTheta; + } + + ///////////////////////////////////////////////////////////////////// + + Condition * OBBCondition::copy() { + return new OBBCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of OBBCondFactory + ///////////////////////////////////////////////////////////////////// + + OBBCondFactory::OBBCondFactory() : SpaceCondFactory() { + _pivotXID = _attrSet.addFloatAttribute( "pivot_x", true /*required*/ ); + _pivotYID = _attrSet.addFloatAttribute( "pivot_y", true /*required*/ ); + _widthID = _attrSet.addFloatAttribute( "width", true /*required*/ ); + _heightID = _attrSet.addFloatAttribute( "height", true /*required*/ ); + _angleID = _attrSet.addFloatAttribute( "angle", true /*required*/ ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool OBBCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + OBBCondition * cond = dynamic_cast< OBBCondition * >( condition ); + assert( cond != 0x0 && "Trying to set the properties of a OBB condition on an incompatible object" ); + + if ( !SpaceCondFactory::setFromXML( cond, node, behaveFldr ) ) return false; + + cond->set( Vector2( _attrSet.getFloat( _pivotXID ), _attrSet.getFloat( _pivotYID ) ), + _attrSet.getFloat( _widthID ), _attrSet.getFloat( _heightID ), + _attrSet.getFloat( _angleID ) * DEG_TO_RAD + ); + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondSpace.h b/src/Menge/MengeCore/BFSM/Transitions/CondSpace.h new file mode 100644 index 00000000..b98cba68 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondSpace.h @@ -0,0 +1,538 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CondSpace.h + * @brief The definition of space-based conditions. I.e. those conditions which are + * triggered based on an agent entering or leaving a particular space. + */ + +#ifndef __COND_SPACE_H__ +#define __COND_SPACE_H__ + +#include "CoreConfig.h" +#include "Transitions/Condition.h" +#include "Transitions/ConditionFactory.h" +#include "Math/Geometry2D.h" +#include "fsmCommon.h" + +namespace Menge { + + namespace BFSM { + //forward declartions + class SpaceCondFactory; + + /*! + * @brief The abstact base class for spatial conditions. This includes all + * conditions which define a geometric region and then determines + * that the condition is met by either entering or exiting the region. + */ + class MENGE_API SpaceCondition : public Condition { + public: + /*! + * @brief Constructor. + */ + SpaceCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + SpaceCondition( const SpaceCondition & cond ); + + protected: + /*! + * @brief Constructor. + */ + ~SpaceCondition(); + + public: + /*! + * @brief The AutoCondition is always met -- it is a tautology. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + friend class SpaceCondFactory; + protected: + /*! + * @brief Determines if a point is inside the test region. + * + * Purely a virtual function. Derived transitions must override this function. + * + * @param pt The point to test w.r.t. the transition region. + * @returns True if the transition region contains the given point. + */ + virtual bool containsPoint( const Vector2 & pt ) const = 0; + + /*! + * @brief Determines if the transition happens when the agent is + * outside (true) or inside (false). + */ + bool _outsideActive; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the SpaceCondition + */ + class MENGE_API SpaceCondFactory : public ConditionFactory { + public: + /*! + * @brief Constructor. + */ + SpaceCondFactory(); + + protected: + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "inside" bool attribute. + */ + size_t _insideID; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A transition based on spatial relationship with a circle. + * + * The agent will transition when it reaches the relationship (inside or outside) + * to the defined circle. + */ + class MENGE_API CircleCondition : public SpaceCondition, public CircleShape { + public: + /*! + * @brief Constructor. + */ + CircleCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + CircleCondition( const CircleCondition & cond ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + + protected: + /*! + * @brief Determines if a point is inside the test region. + * + * @param pt The point to test w.r.t. the transition region. + * @returns True if the transition region contains the given point. + */ + virtual bool containsPoint( const Vector2 & pt ) const { return CircleShape::containsPoint( pt ); } + }; + + /*! + * @brief The factory for creating the SpaceCondition + */ + class MENGE_API CircleCondFactory : public SpaceCondFactory { + public: + /*! + * @brief Constructor. + */ + CircleCondFactory(); + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "circle"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The circle condition. It becomes active when an agent achieves "\ + "a particular relationship (inside/outside) with a static circle in the " \ + "environment."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new CircleCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "center_x" float attribute. + */ + size_t _centerXID; + + /*! + * @brief The identifier for the "center_y" float attribute. + */ + size_t _centerYID; + + /*! + * @brief The identifier for the "radius" float attribute. + */ + size_t _radiusID; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A transition based on spatial relationship with an axis-aligned bounding box (AABB). + * + * The agent will transition when it reaches the relationship (inside or outside) + * to the defined axis-aligned bounding box (AABB). + */ + class MENGE_API AABBCondition : public SpaceCondition, public AABBShape { + public: + /*! + * @brief Constructor. + */ + AABBCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + AABBCondition( const AABBCondition & cond ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + protected: + /*! + * @brief Determines if a point is inside the test region. + * + * @param pt The point to test w.r.t. the transition region. + * @returns True if the transition region contains the given point. + */ + virtual bool containsPoint( const Vector2 & pt ) const { return AABBShape::containsPoint( pt ); } + }; + + /*! + * @brief The factory for creating the AABBCondition + */ + class MENGE_API AABBCondFactory : public SpaceCondFactory { + public: + /*! + * @brief Constructor. + */ + AABBCondFactory(); + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "AABB"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The axis-aligned bounding box (AABB) condition. It becomes active when an agent achieves "\ + "a particular relationship (inside/outside) with a static axis-aligned bounding box in the " \ + "environment."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new AABBCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "min_x" float attribute. + */ + size_t _minXID; + + /*! + * @brief The identifier for the "min_y" float attribute. + */ + size_t _minYID; + + /*! + * @brief The identifier for the "max_x" float attribute. + */ + size_t _maxXID; + + /*! + * @brief The identifier for the "max_y" float attribute. + */ + size_t _maxYID; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A transition based on spatial relationship with an axis-aligned bounding box (AABB). + * + * The agent will transition when it reaches the relationship (inside or outside) + * to the defined axis-aligned bounding box (AABB). + */ + class MENGE_API OBBCondition : public SpaceCondition, public OBBShape { + public: + /*! + * @brief Constructor. + */ + OBBCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + OBBCondition( const OBBCondition & cond ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + protected: + /*! + * @brief Determines if a point is inside the test region. + * + * @param pt The point to test w.r.t. the transition region. + * @returns True if the transition region contains the given point. + */ + virtual bool containsPoint( const Vector2 & pt ) const { return OBBShape::containsPoint( pt ); } + }; + + /*! + * @brief The factory for creating the OBBCondition + */ + class MENGE_API OBBCondFactory : public SpaceCondFactory { + public: + /*! + * @brief Constructor. + */ + OBBCondFactory(); + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "OBB"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The oriented bounding box (OBB) condition. It becomes active when an agent achieves "\ + "a particular relationship (inside/outside) with a static oriented bounding box in the " \ + "environment."; + } + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new OBBCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "pivot_x" float attribute. + */ + size_t _pivotXID; + + /*! + * @brief The identifier for the "pivot_y" float attribute. + */ + size_t _pivotYID; + + /*! + * @brief The identifier for the "width" float attribute. + */ + size_t _widthID; + + /*! + * @brief The identifier for the "height" float attribute. + */ + size_t _heightID; + + /*! + * @brief The identifier for the "angle" float attribute. + */ + size_t _angleID; + }; + + } // namespace BFSM +} + +#endif // __COND_SPACE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondTimer.cpp b/src/Menge/MengeCore/BFSM/Transitions/CondTimer.cpp new file mode 100644 index 00000000..af3eaa3b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondTimer.cpp @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "CondTimer.h" +#include "Core.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of TimerCondition + /////////////////////////////////////////////////////////////////////////// + + TimerCondition::TimerCondition():_triggerTimes(), _durGen(0x0) { + } + + /////////////////////////////////////////////////////////////////////////// + + TimerCondition::TimerCondition( const TimerCondition & cond ):Condition(cond) { + _triggerTimes.insert( cond._triggerTimes.begin(), cond._triggerTimes.end() ); + _durGen = cond._durGen->copy(); + } + + /////////////////////////////////////////////////////////////////////////// + + TimerCondition::~TimerCondition() { + if ( _durGen ) delete _durGen; // TODO: This should be a destroy call as well. + } + + /////////////////////////////////////////////////////////////////////////// + + void TimerCondition::onEnter( Agents::BaseAgent * agent ) { + _lock.lockWrite(); + _triggerTimes[ agent->_id ] = Menge::SIM_TIME + _durGen->getValue(); + _lock.releaseWrite(); + } + + /////////////////////////////////////////////////////////////////////////// + + void TimerCondition::onLeave( Agents::BaseAgent * agent ) { + _lock.lockWrite(); + std::map< size_t, float >::iterator itr = _triggerTimes.find( agent->_id ); + assert( itr != _triggerTimes.end() && "Agent exiting a timer condition that never entered" ); + _triggerTimes.erase( itr ); + _lock.releaseWrite(); + } + + /////////////////////////////////////////////////////////////////////////// + + bool TimerCondition::conditionMet( Agents::BaseAgent * agent, const Goal * goal ) { + _lock.lockRead(); + bool result = _triggerTimes[ agent->_id ] <= Menge::SIM_TIME; + _lock.releaseRead(); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + + Condition * TimerCondition::copy() { + return new TimerCondition( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of TimerCondFactory + ///////////////////////////////////////////////////////////////////// + + TimerCondFactory::TimerCondFactory() : ConditionFactory() { + _perAgentID = _attrSet.addBoolAttribute( "per_agent", true /*required*/ ); + _durGenID = _attrSet.addFloatDistAttribute( "", true, 0.f, 1.f ); + } + + /////////////////////////////////////////////////////////////////////////// + + bool TimerCondFactory::setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + TimerCondition * tCond = dynamic_cast< TimerCondition * >( condition ); + assert( tCond != 0x0 && "Trying to set the properties of a timer condition on an incompatible object" ); + + if ( !ConditionFactory::setFromXML( condition, node, behaveFldr ) ) return false; + + bool useGlobal = !_attrSet.getBool( _perAgentID ); + FloatGenerator * gen = _attrSet.getFloatGenerator( _durGenID ); + if ( useGlobal ) { + // This allows for a randomly generated const value. As opposed to simply specifying a global const. + tCond->_durGen = new ConstFloatGenerator( gen->getValue() ); + delete gen; // TODO: determine if this is safe across dlls. It may need to be a destroy. + } else { + tCond->_durGen = gen; + } + + return true; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/CondTimer.h b/src/Menge/MengeCore/BFSM/Transitions/CondTimer.h new file mode 100644 index 00000000..815a4917 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/CondTimer.h @@ -0,0 +1,227 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CondTimer.h + * @brief The definition of the timer-based condition. + */ + +#ifndef __COND_TIMER_H__ +#define __COND_TIMER_H__ + +#include "CoreConfig.h" +#include "Transitions/Condition.h" +#include "Transitions/ConditionFactory.h" +#include "fsmCommon.h" +#include "ReadersWriterLock.h" +#include //TODO: Replace this with a hash_map + +namespace Menge { + + namespace BFSM { + + // forward declarations + class TimerCondFactory; + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The definition of the timer condition. + * + * The time condition becomes active when the agent has been in the state + * at least the amount of time specified by the transition properties. + * The amount of time can be specified globally or per agent and, in the + * case of a per-agent duration, can be specified using the value + * distributions (FloatGenerator). + */ + class MENGE_API TimerCondition : public Condition { + public: + /*! + * @brief Constructor. + */ + TimerCondition(); + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + TimerCondition( const TimerCondition & cond ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy(); + + protected: + /*! + * @brief Constructor. + */ + ~TimerCondition(); + + public: + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ); + + /*! + * @brief The AutoCondition is always met -- it is a tautology. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ); + + friend class TimerCondFactory; + protected: + /*! + * @brief The trigger time for agents currently effected by this transition. + */ + std::map< size_t, float > _triggerTimes; + + /*! + * @brief The generator for determining the per-agent duration. + */ + FloatGenerator * _durGen; + + /*! + * @brief Lock to protect _triggerTimes; + */ + ReadersWriterLock _lock; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the TimerCondition + */ + class MENGE_API TimerCondFactory : public ConditionFactory { + public: + /*! + * @brief Constructor. + */ + TimerCondFactory(); + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "timer"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The timer condition. It becomes active when the agent has "\ + "remained in the state at least a user-specified length of time."; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Condition * instance() const { return new TimerCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "per_agent" boolean attribute. + */ + size_t _perAgentID; + + /*! + * @brief The identifier for the duration float distribution attribute. + */ + size_t _durGenID; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __COND_TIMER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/Condition.h b/src/Menge/MengeCore/BFSM/Transitions/Condition.h new file mode 100644 index 00000000..46f7e1ff --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/Condition.h @@ -0,0 +1,134 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Condition.h + * @brief The basis for determining the conditions under which + * transitions become "active" (and are taken). + */ +#ifndef __CONDITION_H__ +#define __CONDITION_H__ + +#include "CoreConfig.h" +#include "fsmCommon.h" +#include "Element.h" + +namespace Menge { + + // forward declarations + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + // forward declaration + class Goal; + + /*! + * @brief The base class for transition conditions. + * + * This class is an abstract class used to define arbitrary conditions + * for finite-state-machine transitions. + */ + class MENGE_API Condition : public Element { + public: + /*! + * @brief Constructor. + */ + Condition() : Element() {} + + /*! + * @brief Copy Constructor. + * + * @param cond The condition to copy from. + */ + Condition( const Condition & cond ){} + + protected: + /*! + * @brief Protected destructor. + */ + virtual ~Condition() {} + + public: + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ){} + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ){} + + /*! + * @brief Reports if the conditions have been met. + * + * This function defines the main functionality of a definition. + * Given the current agent and its internal state, it determines if + * the conditions have been met. This should be overridden by each + * sub-class. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const Goal * goal ) = 0; + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual Condition * copy() = 0; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __CONDITION_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.cpp b/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.cpp new file mode 100644 index 00000000..6267dcca --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.cpp @@ -0,0 +1,69 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ConditionDatabase.h" +#include "Transitions/CondAuto.h" +#include "Transitions/CondTimer.h" +#include "Transitions/CondSpace.h" +#include "Transitions/CondGoal.h" +#include "Transitions/CondBoolean.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::ConditionFactory, BFSM::Condition >::getElementName() { return "condition"; } + + template <> + void ElementDB< BFSM::ConditionFactory, BFSM::Condition >::addBuiltins() { + addFactory( new BFSM::AutoCondFactory() ); + addFactory( new BFSM::TimerCondFactory() ); + addFactory( new BFSM::CircleCondFactory() ); + addFactory( new BFSM::AABBCondFactory() ); + addFactory( new BFSM::OBBCondFactory() ); + addFactory( new BFSM::GoalCondFactory() ); + addFactory( new BFSM::AndCondFactory() ); + addFactory( new BFSM::OrCondFactory() ); + addFactory( new BFSM::NotCondFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.h b/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.h new file mode 100644 index 00000000..65d9c96f --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/ConditionDatabase.h @@ -0,0 +1,79 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ConditionDatabase.h + * @brief Central database for querying available behavior conditions. + * + * For conditions to be used in the finite state machine, they must register + * themselves into the ConditionDatabase. This is done via the PluginEngine. + */ + +#ifndef __CONDITION_DATABASE_H__ +#define __CONDITION_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Transitions/ConditionFactory.h" +#include "Transitions/Condition.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The database of registered condition implementations. + */ + typedef ElementDB< ConditionFactory, Condition > ConditionDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + /*! + * @brief Explicit specialization of addBuiltins for the Condition Database + */ + template<> void ElementDB< BFSM::ConditionFactory, BFSM::Condition>::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the Condition Database + */ + template<> std::string ElementDB< BFSM::ConditionFactory, BFSM::Condition >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge +#endif // __CONDITION_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/Transitions/ConditionFactory.h b/src/Menge/MengeCore/BFSM/Transitions/ConditionFactory.h new file mode 100644 index 00000000..94c5bbdf --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/ConditionFactory.h @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ConditionFactory.h + * @brief The factory for parsing xml data for transition conditions + * and instantiating the appropriate class. + */ + +#ifndef __CONDITION_FACTORY_H__ +#define __CONDITION_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "Transitions/Condition.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The class for parsing the xml description of a Condition + * and instantiating particular instances. + */ + class MENGE_API ConditionFactory : public ElementFactory< Condition > { + }; + } // namespace BFSM +} // namespace Menge +#endif // __CONDITION_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/Target.cpp b/src/Menge/MengeCore/BFSM/Transitions/Target.cpp new file mode 100644 index 00000000..b733efd8 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/Target.cpp @@ -0,0 +1,99 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Transitions/Target.h" +#include "Logger.h" +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SingleTarget + ///////////////////////////////////////////////////////////////////// + + TransitionTarget::TransitionTarget() : Element() { + } + + ///////////////////////////////////////////////////////////////////// + + TransitionTarget::TransitionTarget( const TransitionTarget & tgt ){} + + ///////////////////////////////////////////////////////////////////// + + TransitionTarget::~TransitionTarget() { + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of SingleTarget + ///////////////////////////////////////////////////////////////////// + + SingleTarget::SingleTarget():TransitionTarget(),_nextName(""), _next(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + SingleTarget::SingleTarget( const SingleTarget & tgt ):TransitionTarget(tgt),_nextName(tgt._nextName), _next(tgt._next) { + } + + ///////////////////////////////////////////////////////////////////// + + SingleTarget::SingleTarget( const std::string & toName ):_nextName(toName), _next(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + bool SingleTarget::connectStates( std::map< std::string, State * > & stateMap ) { + if ( stateMap.find( _nextName ) == stateMap.end() ) { + logger << Logger::ERR_MSG << "SingleTarget with invalid to node name: " << _nextName << "\n"; + return false; + } + _next = stateMap[ _nextName ]; + return true; + } + + ///////////////////////////////////////////////////////////////////// + + TransitionTarget * SingleTarget::copy() { + return new SingleTarget( *this ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/Target.h b/src/Menge/MengeCore/BFSM/Transitions/Target.h new file mode 100644 index 00000000..2a0faa1d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/Target.h @@ -0,0 +1,230 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Target.h + * @brief The basis for determing what an active transition leads to. + */ + +#ifndef __TARGET_H__ +#define __TARGET_H__ + +#include "CoreConfig.h" +#include "Element.h" +#include +#include + +namespace Menge { + + // forward declarations + namespace Agents { + class BaseAgent; + } + + namespace BFSM { + // forward declarations + class State; + class Goal; + + /*! + * @brief The base class for transition targets. + * + * A transition target is the state a transition moves an agent to. + * In the simplest case, the transition simply connects two states and + * when the transition is active, the agent moves from the source state + * to the destination state. + * + * However, Target's can be more complex. The destination can be one of + * a set of states selected by arbitrary criteria (such as probability). + * The target is responsible for providing a next state according to its + * criteria upon request. + */ + class MENGE_API TransitionTarget : public Element { + public: + /*! + * @brief Constructor. + */ + TransitionTarget(); + + /*! + * @brief Copy constructor. + * + * @param tgt TransitionTarget to copy. + */ + TransitionTarget( const TransitionTarget & tgt ); + + protected: + /*! + * @brief Protected destructor. + */ + virtual ~TransitionTarget(); + + public: + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ){} + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ){} + + /*! + * @brief Determines the next state for the given agent. + * + * This function defines the main functionality of the target. + * Given the current agent and the class's internal state, it determines + * The state to move the agent into. This should be overridden by each + * sub-class. + * + * @param agent The agent to test the transition for. + * @returns A pointer to the next state. + */ + virtual State * nextState( Agents::BaseAgent * agent ) = 0; + + /*! + * @brief Performs any necessary connections to the target state(s). + * + * Sub-classes must override this because a transition must transition to + * a state. See the sub-classes SingleTransition for an example. + * + * @param stateMap A mapping from state names to state pointers. + * @returns True if connection was successful, false otherwise. + */ + virtual bool connectStates( std::map< std::string, State * > & stateMap ) = 0; + + /*! + * @brief Create a copy of this target. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this target - such that there is no shared + * objects between this and its copy. + */ + virtual TransitionTarget * copy() = 0; + }; + + ///////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A TransitionTarget which assumes there is only one destination + * state. + * + * This will always return a single state, regardless of the agent. + */ + class MENGE_API SingleTarget : public TransitionTarget { + public: + /*! + * @brief Default constructor. + */ + SingleTarget(); + + /*! + * @brief Copy constructor. + * + * @param tgt The transition target to copy. + */ + SingleTarget( const SingleTarget & tgt ); + + /*! + * @brief Constructor. + * + * @param toName The name of the destination (aka "to") node. + */ + SingleTarget( const std::string & toName ); + + // TOOD: Change the goalPoint into a Goal instance + /*! + * @brief Determines the next state for the given agent. + * + * This function defines the main functionality of the target. + * Given the current agent and the class's internal state, it determines + * The state to move the agent into. This should be overridden by each + * sub-class. + * + * @param agent The agent to test the transition for. + * @returns A pointer to the next state. + */ + virtual State * nextState( Agents::BaseAgent * agent ) { return _next; } + + /*! + * @brief Performs any necessary connections to the target state(s). + * + * Sub-classes must override this because a transition must transition to + * a state. See the sub-classes SingleTransition for an example. + * + * @param stateMap A mapping from state names to state pointers. + * @returns True if connection was successful, false otherwise. + */ + virtual bool connectStates( std::map< std::string, State * > & stateMap ); + + /*! + * @brief Create a copy of this target. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this target - such that there is no shared + * objects between this and its copy. + */ + virtual TransitionTarget * copy(); + + + protected: + /*! + * @brief The name of the state to which this transition leads. + */ + std::string _nextName; + + /*! + * @brief a pointer to the state to which this transition leads. + */ + State * _next; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __TARGET_H__ diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.cpp b/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.cpp new file mode 100644 index 00000000..72adfd0b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.cpp @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "TargetDatabase.h" +#include "Transitions/TargetProb.h" +#include "Transitions/TargetReturn.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::TargetFactory, BFSM::TransitionTarget >::getElementName() { return "target"; } + + template <> + void ElementDB< BFSM::TargetFactory, BFSM::TransitionTarget >::addBuiltins() { + // call addFactory on builtins + addFactory( new BFSM::ProbTargetFactory() ); + addFactory( new BFSM::ReturnTargetFactory() ); + } + +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.h b/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.h new file mode 100644 index 00000000..40b25a07 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetDatabase.h @@ -0,0 +1,79 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TargetDatabase.h + * @brief Central database for querying available behavior transition targets. + * + * For transition targets to be used in the finite state machine, they must register + * themselves into the TargetDatabase. This is done via the PluginEngine. + */ + +#ifndef __TARGET_DATABASE_H__ +#define __TARGET_DATABASE_H__ + +#include "ElementDatabase.h" +#include "Transitions/TargetFactory.h" +#include "Transitions/Target.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The database of registered transition targets. + */ + typedef ElementDB< TargetFactory, TransitionTarget > TargetDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + /*! + * @brief Explicit specialization of addBuiltins for the TransitionTarget Database + */ + template<> void ElementDB< BFSM::TargetFactory, BFSM::TransitionTarget>::addBuiltins(); + + /*! + * @brief Explicit specialization of getElementName for the TransitionTarget Database + */ + template<> std::string ElementDB< BFSM::TargetFactory, BFSM::TransitionTarget >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge +#endif // __TARGET_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetFactory.h b/src/Menge/MengeCore/BFSM/Transitions/TargetFactory.h new file mode 100644 index 00000000..d643a749 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetFactory.h @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TargetFactory.h + * @brief The factory for parsing xml data for TransitionTarget + * and instantiating the appropriate class. + */ + +#ifndef __TARGET_FACTORY_H__ +#define __TARGET_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "Transitions/Target.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a TransitionTarget + * and instantiating particular instances. + */ + class MENGE_API TargetFactory : public ElementFactory< TransitionTarget > { + }; + + } // namespace BFSM +} // namespace Menge +#endif // __TARGET_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetProb.cpp b/src/Menge/MengeCore/BFSM/Transitions/TargetProb.cpp new file mode 100644 index 00000000..343dbcb3 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetProb.cpp @@ -0,0 +1,139 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "TargetProb.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of ProbTarget + /////////////////////////////////////////////////////////////////////////// + + ProbTarget::ProbTarget():TransitionTarget(), _randNum(0.f,1.f),_totalWeight(0.f),_targetNames(), _targets() { + } + + /////////////////////////////////////////////////////////////////////////// + + ProbTarget::ProbTarget( const ProbTarget & tgt ):TransitionTarget(tgt), _randNum(tgt._randNum),_totalWeight(tgt._totalWeight), _targetNames(tgt._targetNames), _targets(tgt._targets) { + } + + /////////////////////////////////////////////////////////////////////////// + + State * ProbTarget::nextState( Agents::BaseAgent * agent ) { + const size_t TGT_COUNT = _targets.size(); + assert( TGT_COUNT > 0 && "Trying to transition to an empty set of states" ); + + const float TGT_WEIGHT = _totalWeight * _randNum.getValue(); + + State * state = 0x0; + float accumWeight = 0.f; + std::map< State *, float >::const_iterator itr = _targets.begin(); + while ( accumWeight <= TGT_WEIGHT && itr != _targets.end() ) { + state = itr->first; + accumWeight += itr->second; + ++itr; + } + return state; + } + + /////////////////////////////////////////////////////////////////////////// + + bool ProbTarget::connectStates( std::map< std::string, State * > & stateMap ) { + _totalWeight = 0.f; + std::list< std::pair< float, std::string > >::iterator itr = _targetNames.begin(); + for ( ; itr != _targetNames.end(); ++itr ) { + const float weight = (*itr).first; + std::string name = (*itr).second; + if ( stateMap.find( name ) == stateMap.end() ) { + logger << Logger::ERR_MSG << "Probability Target with invalid state name: " << name << "."; + return false; + } + _totalWeight += weight; + _targets[ stateMap[ name ] ] = weight; + } + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + TransitionTarget * ProbTarget::copy() { + return new ProbTarget( *this ); + } + + /////////////////////////////////////////////////////////////////////////// + // Implementation of ProbTargetFactory + /////////////////////////////////////////////////////////////////////////// + + bool ProbTargetFactory::setFromXML( TransitionTarget * target, TiXmlElement * node, const std::string & behaveFldr ) const { + ProbTarget * tgt = dynamic_cast< ProbTarget * >( target ); + assert( tgt != 0x0 && "Trying to set the properties of a probabalistic transition target on an incompatible object" ); + + if ( ! TargetFactory::setFromXML( tgt, node, behaveFldr ) ) return false; + + // ProbTargetFactory does *not* use the attribute set directly + // All of its parameters are child tags which it parses by hand. + // Scan the child tags for State tags + for ( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == "State" ) { + // read the weight + double weight; + if ( ! child->Attribute( "weight", &weight ) ) { + logger << Logger::WARN_MSG << "The State tag on line " << child->Row() << " is missing the \"weight\" property. It is assumed to be 1.0."; + weight = 1.f; + } + + // read the name + const char * nameCStr = child->Attribute( "name" ); + if ( nameCStr == 0x0 ) { + logger << Logger::ERR_MSG << "The State tag on line " << child->Row() << " hasn't specified the \"name\" property."; + return false; + } + tgt->_targetNames.push_back( std::pair< float, std::string >( (float)weight, std::string( nameCStr ) ) ); + } else { + logger << Logger::ERR_MSG << "Found an incompatible xml tag (" << child->ValueStr() << ") as a child of a probabalistic transition target tag on line " << child->Row() << "."; + return false; + } + } + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetProb.h b/src/Menge/MengeCore/BFSM/Transitions/TargetProb.h new file mode 100644 index 00000000..a593b9f3 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetProb.h @@ -0,0 +1,213 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TargetProb.h + * @brief Defines a transition target probabilistically. + */ + +#ifndef __TARGET_PROB_H__ +#define __TARGET_PROB_H__ + +#include "CoreConfig.h" +#include "Target.h" +#include "TargetFactory.h" +#include "fsmCommon.h" +#include + +namespace Menge { + + namespace BFSM { + + // forward declarations + class State; + class ProbTargetFactory; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The definition of the probabalistic target. + * + * Typically, the FSM will be deterministic in that if an agent is in + * a current state, with a particualr condition being true, it will + * transition to a deterministic state. The probabalistic target allows + * the transition to be implicitly connected to a number of states. + * Upon transitioning, the destination state is computed randomly + * from the set. + */ + class MENGE_API ProbTarget : public TransitionTarget { + public: + /*! + * @brief Constructor + */ + ProbTarget(); + + /*! + * @brief Copy constructor. + * + * @param tgt The target to copy. + */ + ProbTarget( const ProbTarget & tgt ); + + /*! + * @brief Determines the next state for the given agent. + * + * This function defines the main functionality of the target. + * Given the current agent and the class's internal state, it determines + * The state to move the agent into. This should be overridden by each + * sub-class. + * + * @param agent The agent to test the transition for. + * @returns A pointer to the next state. + */ + virtual State * nextState( Agents::BaseAgent * agent ); + + /*! + * @brief Performs any necessary connections to the target state(s). + * + * Sub-classes must override this because a transition must transition to + * a state. See the sub-classes SingleTransition for an example. + * + * @param stateMap A mapping from state names to state pointers. + * @returns True if connection was successful, false otherwise. + */ + virtual bool connectStates( std::map< std::string, State * > & stateMap ); + + /*! + * @brief Create a copy of this target. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this target - such that there is no shared + * objects between this and its copy. + */ + virtual TransitionTarget * copy(); + + friend class ProbTargetFactory; + protected: + /*! + * @brief The random number generator for selecting the next state. + */ + UniformFloatGenerator _randNum; + + /*! + * @brief The total weight of all the target states. + * + * This gets set after a call to connectStates. + */ + float _totalWeight; + + /*! + * @brief The set of target state *names* and their relative weights. + */ + std::list< std::pair< float, std::string > > _targetNames; + + /*! + * @brief The set of target states and their corresponding relative + * weights. + */ + std::map< State *, float > _targets; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the ProbTarget + */ + class MENGE_API ProbTargetFactory : public TargetFactory { + public: + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "prob"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "The probabalistic transition target. This allows a state to"\ + " transition to a randomly selected member of a set of states. "\ + "The state selected is based on weighted probabilities."; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated TransitionTarget class. + */ + virtual TransitionTarget * instance() const { return new ProbTarget(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param target A pointer to the transition target whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( TransitionTarget * target, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __TARGET_PROB_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.cpp b/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.cpp new file mode 100644 index 00000000..534ca578 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.cpp @@ -0,0 +1,107 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "TargetReturn.h" +#include "tinyxml.h" +#include "Core.h" +#include +#include "FSM.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of ReturnTarget + /////////////////////////////////////////////////////////////////////////// + + ReturnTarget::ReturnTarget():TransitionTarget(), _targets() { + } + + /////////////////////////////////////////////////////////////////////////// + + ReturnTarget::ReturnTarget( const ReturnTarget & tgt):TransitionTarget(tgt), _targets(tgt._targets) { + } + + /////////////////////////////////////////////////////////////////////////// + + void ReturnTarget::onEnter( Agents::BaseAgent * agent ) { + _lock.lockWrite(); + assert( Menge::ACTIVE_FSM != 0x0 && "Undefined FSM pointer" ); + _targets[ agent->_id ] = Menge::ACTIVE_FSM->getCurrentState( agent ); + _lock.releaseWrite(); + } + + /////////////////////////////////////////////////////////////////////////// + + void ReturnTarget::onLeave( Agents::BaseAgent * agent ) { + _lock.lockWrite(); + assert( Menge::ACTIVE_FSM != 0x0 && "Undefined FSM pointer" ); + std::map< size_t, State * >::iterator itr = _targets.find( agent->_id ); + if ( itr != _targets.end() ) { + _targets.erase( agent->_id ); + } + _lock.releaseWrite(); + } + + /////////////////////////////////////////////////////////////////////////// + + State * ReturnTarget::nextState( Agents::BaseAgent * agent ) { + _lock.lockRead(); + std::map< size_t, State * >::iterator itr = _targets.find( agent->_id ); + assert( itr != _targets.end() && "Using a return target for an agent with no return value" ); + State * next = itr->second; + _lock.releaseRead(); + return next; + } + + /////////////////////////////////////////////////////////////////////////// + + bool ReturnTarget::connectStates( std::map< std::string, State * > & stateMap ){ + // No work is required because the target is determined dynamically + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + TransitionTarget * ReturnTarget::copy() { + return new ReturnTarget( *this ); + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.h b/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.h new file mode 100644 index 00000000..58126e14 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/TargetReturn.h @@ -0,0 +1,200 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TargetReturn.h + * @brief Defines a transition target that returns the agent to the state from + * which he entered this state. + */ + +#ifndef __TARGET_RETURN_H__ +#define __TARGET_RETURN_H__ + +#include "CoreConfig.h" +#include "Target.h" +#include "TargetFactory.h" +#include "fsmCommon.h" +#include "ReadersWriterLock.h" +#include + +namespace Menge { + + namespace BFSM { + + // forward declarations + class State; + class ReturnTargetFactory; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The definition of the return target. + * + * The return target causes the agent to go back to the state from which + * the agent transitioned to the current state. However, this isn't necessarily + * the *literal* previous state. The FSM can advance multiple states in a single + * time step. This target returns the agent to the state it was in at the beginning + * of this call to advance (and not the immediately previous state which was simply + * passed through.) + */ + class MENGE_API ReturnTarget : public TransitionTarget { + public: + /*! + * @brief Constructor + */ + ReturnTarget(); + + /*! + * @brief Copy constructor + * + * @param tgt The transition target to copy. + */ + ReturnTarget( const ReturnTarget & tgt); + + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * Sub-classes should use this function as the opportunity to cache any + * particular per-agent data. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + virtual void onLeave( Agents::BaseAgent * agent ); + + /*! + * @brief Determines the next state for the given agent. + * + * This function defines the main functionality of the target. + * Given the current agent and the class's internal state, it determines + * The state to move the agent into. This should be overridden by each + * sub-class. + * + * @param agent The agent to test the transition for. + * @returns A pointer to the next state. + */ + virtual State * nextState( Agents::BaseAgent * agent ); + + /*! + * @brief Performs any necessary connections to the target state(s). + * + * Sub-classes must override this because a transition must transition to + * a state. See the sub-classes SingleTransition for an example. + * + * @param stateMap A mapping from state names to state pointers. + * @returns True if connection was successful, false otherwise. + */ + virtual bool connectStates( std::map< std::string, State * > & stateMap ); + + /*! + * @brief Create a copy of this target. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this target - such that there is no shared + * objects between this and its copy. + */ + virtual TransitionTarget * copy(); + + friend class ReturnTargetFactory; + protected: + /*! + * @brief A mapping between an agent id and its return state. + */ + std::map< size_t, State * > _targets; + + /*! + * @brief Lock to protect _targets; + */ + ReadersWriterLock _lock; + + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for creating the ReturnTarget + */ + class MENGE_API ReturnTargetFactory : public TargetFactory { + public: + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "return"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Defines the transition target as the state the agent was in when "\ + "it advanced to this state."; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All TargetFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to TargetFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated TransitionTarget class. + */ + virtual TransitionTarget * instance() const { return new ReturnTarget(); } + }; + + } // namespace BFSM +} // namespace Menge +#endif // __TARGET_RETURN_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/Transition.cpp b/src/Menge/MengeCore/BFSM/Transitions/Transition.cpp new file mode 100644 index 00000000..42d83669 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/Transition.cpp @@ -0,0 +1,162 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Transition.h" +#include "Transitions/Condition.h" +#include "Transitions/ConditionDatabase.h" +#include "Transitions/Target.h" +#include "Transitions/TargetDatabase.h" +#include "BaseAgent.h" +#include "FSM.h" +#include "tinyxml.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Transition + ///////////////////////////////////////////////////////////////////// + + Transition::Transition( const Transition & trans ):_condition(trans._condition->copy()), _target(trans._target->copy()) { + } + + ///////////////////////////////////////////////////////////////////// + + Transition::Transition( Condition * condition, TransitionTarget * target ):_condition(condition), _target(target) { + } + + ///////////////////////////////////////////////////////////////////// + + Transition::~Transition() { + if ( _condition ) _condition->destroy(); + if ( _target ) _target->destroy(); + } + + ///////////////////////////////////////////////////////////////////// + + bool Transition::connectStates( std::map< std::string, State * > & stateMap ) { + assert( _target && "Connecting states for a transition with no target" ); + return _target->connectStates( stateMap ); + } + + ///////////////////////////////////////////////////////////////////// + + void Transition::onEnter( Agents::BaseAgent * agent ) { + assert( _condition && "Entering transition with no defined condition" ); + assert( _target && " Entering transition with no defined target" ); + _condition->onEnter( agent ); + _target->onEnter( agent ); + } + + ///////////////////////////////////////////////////////////////////// + + void Transition::onLeave( Agents::BaseAgent * agent ) { + assert( _condition && "Leaving transition with no defined condition" ); + assert( _target && " Leaving transition with no defined target" ); + _condition->onLeave( agent ); + _target->onLeave( agent ); + } + + ///////////////////////////////////////////////////////////////////// + + State * Transition::test( Agents::BaseAgent * agent, const Goal * goal ) { + if ( _condition->conditionMet( agent, goal ) ) { + return _target->nextState( agent ); + } + return 0x0; + } + + ///////////////////////////////////////////////////////////////////// + + void Transition::getTasks( FSM * fsm ) { + fsm->addTask( _condition->getTask() ); + fsm->addTask( _target->getTask() ); + } + + ///////////////////////////////////////////////////////////////////// + + Transition * Transition::copy() { + return new Transition( *this ); + } + + ///////////////////////////////////////////////////////////////////// + + Transition * parseTransition( TiXmlElement * node, const std::string & behaveFldr, std::string & fromName ) { + // 1) test "from" name - store if valid + bool valid = true; + const char * fromCStr = node->Attribute( "from" ); + if ( fromCStr == 0x0 ) { + logger << Logger::ERR_MSG << "Transition defined on line " << node->Row() << " missing \"from\" attribute."; + valid = false; + } + fromName = fromCStr; + + // 2) test "to" name - create SingleTarget if valid (and store) + Condition * condition = 0x0; + TransitionTarget * target = 0x0; + const char * toCStr = node->Attribute("to"); + if ( toCStr != 0x0 ) { + target = new SingleTarget( std::string( toCStr ) ); + } + // 3) Look for child tags: Condition and Target + for ( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement() ) { + if ( child->ValueStr() == "Condition" ) { + condition = ConditionDB::getInstance( child, behaveFldr ); + } else if ( child->ValueStr() == "Target" ) { + if ( target ) target->destroy(); + target = TargetDB::getInstance( child, behaveFldr ); + } else { + logger << Logger::ERR_MSG << "Unrecognized child tag of a Transition on line " << child->Row() << ": " << child->ValueStr() << "."; + valid = false; + } + } + + valid = valid && condition != 0x0 && target != 0x0; + // 4) If no Condition tag exists, it fails, if no Target tag exists && there was no to tag, it fails + if ( ! valid ) { + logger << Logger::ERR_MSG << "Missing target and/or condition specification for the Transition defined on line " << node->Row() << "."; + if ( condition ) condition->destroy(); + if ( target ) target->destroy(); + return 0x0; + } + // If everything is valid, instantiate the transition, and the Transition + return new Transition( condition, target ); + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/Transitions/Transition.h b/src/Menge/MengeCore/BFSM/Transitions/Transition.h new file mode 100644 index 00000000..887ed7a9 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/Transitions/Transition.h @@ -0,0 +1,171 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Transition.h + * @brief The definition of state transitions in the BFSM + */ + +#ifndef __TRANSITION_H__ +#define __TRANSITION_H__ + +#include "fsmCommon.h" +#include + +namespace Menge { + + namespace BFSM { + + class State; + class Condition; + class TransitionTarget; + class FSM; + class Goal; + + /*! + * @brief The transition between BFSM states. + * + * Transitions can key on arbitrary state. For each agent, the + * transition is "tested". If the condition is met, the transition is + * active and that reports to the state (which then "follows" the transition). + */ + class Transition { + public: + /*! + * @brief Copy constructor. + * + * @param trans The transition to copy to this one. + */ + Transition( const Transition & trans ); + + /*! + * @brief Constructor + * + * The transition takes ownership of the Condition and TransitionTarget + * given as parameters to the constructor and will destroy them in their + * destructor. As such, they should be unique. + * + * @param condition The condition instance for this transition. + * @param target The target instance for this transition. + */ + Transition( Condition * condition, TransitionTarget * target ); + + /*! + * @brief Destructor. + */ + ~Transition(); + + /*! + * @brief Performs any necessary connections to the "to" state. + * + * Sub-classes must override this because a transition must transition to + * a state. See the sub-classes SingleTransition for an example. + * + * @param stateMap A mapping from state names to state pointers. + * @returns True if connection was successful, false otherwise. + */ + bool connectStates( std::map< std::string, State * > & stateMap ); + + /*! + * @brief Called when an agent enters a state with this exiting transition. + * + * @param agent The agent who has entered the state which uses + * this transition. + */ + virtual void onEnter( Agents::BaseAgent * agent ); + + /*! + * @brief Called when an agent exits the state with this transition. + * + * @param agent The agent who left the state. + */ + void onLeave( Agents::BaseAgent * agent ); + + /*! + * @brief Tests to see if this transition's conditions are met. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns A pointer to the next state if the test passes, otherwise + * returns NULL. + */ + State * test( Agents::BaseAgent * agent, const Goal * goal ); + + /*! + * @brief Gets the tasks for all of the transitions target and condition. + * + * @param fsm A pointer to the fsm. Tasks are fed to the fsm. + */ + void getTasks( FSM * fsm ); + + /*! + * @brief Creats a deep copy of this transition. + * + * @returns A new transition whose values are identical to this one. + */ + Transition * copy(); + + protected: + + /*! + * @brief The Condition instance for this transition. + */ + Condition * _condition; + + /*! + * @brief The target for this transition. + */ + TransitionTarget * _target; + }; + + /*! + * @brief Parses a TinyXML element containing a transition specification + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @param fromName The name of the state from which the transition originates + * will be set in this string. + * @returns A pointer to the new transition implementation (NULL if no valid + * instance could be created). + */ + Transition * parseTransition( TiXmlElement * node, const std::string & behaveFldr, std::string & fromName ); + + } // namespace BFSM +} // namespace Menge +#endif // __TRANSITION_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.cpp new file mode 100644 index 00000000..f3149c38 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.cpp @@ -0,0 +1,247 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityComponents/VelCompConst.h" +#include "BaseAgent.h" + +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstVelComponent + ///////////////////////////////////////////////////////////////////// + + ConstVelComponent::ConstVelComponent(): VelComponent() { + setVelocity( Vector2( 1.f, 0.f ) ); + } + + ///////////////////////////////////////////////////////////////////// + + ConstVelComponent::ConstVelComponent( const Vector2 & vel ): VelComponent() { + setVelocity( vel ); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + pVel.setSingle( _dir ); + pVel.setSpeed( _speed ); + pVel.setTarget( _dir * ( _speed * 5.f ) + agent->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstVelComponent::setVelocity( const Vector2 & velocity ) { + _dir.set( norm( velocity ) ); + _speed = abs( velocity ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * ConstVelComponent::getContext() { + return new ConstVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstVCContext + ///////////////////////////////////////////////////////////////////// + + ConstVCContext::ConstVCContext( ConstVelComponent * vc ):VelCompContext(),_vc(vc) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string ConstVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Const: " << _vc->getConstVelocity(); + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + // draw preferred velocity + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstVCFactory + ///////////////////////////////////////////////////////////////////// + + ConstVCFactory::ConstVCFactory() : VelCompFactory() { + _xID = _attrSet.addFloatAttribute( "x", true /*required*/ ); + _yID = _attrSet.addFloatAttribute( "y", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ConstVCFactory::setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const { + ConstVelComponent * cvc = dynamic_cast< ConstVelComponent * >( vc ); + assert( cvc != 0x0 && "Trying to set attributes of a const velocity component on an incompatible object" ); + + if ( ! VelCompFactory::setFromXML( vc, node, behaveFldr ) ) return false; + + cvc->setVelocity( Vector2( _attrSet.getFloat( _xID ), _attrSet.getFloat( _yID ) ) ); + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstVelDirComponent + ///////////////////////////////////////////////////////////////////// + + ConstVelDirComponent::ConstVelDirComponent(): VelComponent() { + setDirection( Vector2( 1.f, 0.f ) ); + } + + ///////////////////////////////////////////////////////////////////// + + ConstVelDirComponent::ConstVelDirComponent( const Vector2 & vel ): VelComponent() { + setDirection( vel ); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstVelDirComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + pVel.setSingle( _dir ); + pVel.setSpeed( agent->_prefSpeed ); + pVel.setTarget( _dir * ( agent->_prefSpeed * 5.f ) + agent->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstVelDirComponent::setDirection( const Vector2 & dir ) { + _dir.set( norm( dir ) ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * ConstVelDirComponent::getContext() { + return new ConstDirVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstDirVCContext + ///////////////////////////////////////////////////////////////////// + + ConstDirVCContext::ConstDirVCContext( ConstVelDirComponent * vc ):VelCompContext(),_vc(vc) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string ConstDirVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Const direction: " << _vc->_dir; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void ConstDirVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + // draw preferred velocity + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstDirVCFactory + ///////////////////////////////////////////////////////////////////// + + ConstDirVCFactory::ConstDirVCFactory() : VelCompFactory() { + _xID = _attrSet.addFloatAttribute( "x", true /*required*/ ); + _yID = _attrSet.addFloatAttribute( "y", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ConstDirVCFactory::setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const { + ConstVelDirComponent * cvc = dynamic_cast< ConstVelDirComponent * >( vc ); + assert( cvc != 0x0 && "Trying to set attributes of a const direction velocity component on an incompatible object" ); + + if ( ! VelCompFactory::setFromXML( cvc, node, behaveFldr ) ) return false; + + cvc->setDirection( Vector2( _attrSet.getFloat( _xID ), _attrSet.getFloat( _yID ) ) ); + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ZeroVelComponent + ///////////////////////////////////////////////////////////////////// + + ZeroVelComponent::ZeroVelComponent(): VelComponent() { + } + + ///////////////////////////////////////////////////////////////////// + + void ZeroVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + pVel.setSingle( Vector2(1.f,0.f) ); + pVel.setSpeed( 0.f ); + pVel.setTarget( agent->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * ZeroVelComponent::getContext() { + return new ZeroVCContext(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ZeroVCContext + ///////////////////////////////////////////////////////////////////// + + ZeroVCContext::ZeroVCContext():VelCompContext() { + } + + ///////////////////////////////////////////////////////////////////// + + std::string ZeroVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Zero velocity"; + return ss.str(); + } + + + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.h new file mode 100644 index 00000000..9dafbc60 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompConst.h @@ -0,0 +1,548 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompConst.h + * @brief Provides the definitions of some simple velocity components + * based on constant velocities. + */ + +#ifndef __VEL_COMP_CONST_H__ +#define __VEL_COMP_CONST_H__ + +#include "CoreConfig.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelCompContext.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief A velocity component that always returns a constant velocity. + */ + class MENGE_API ConstVelComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + ConstVelComponent(); + + /*! + * @brief Constructor. + * + * @param vel The preferred velocity to return. + */ + ConstVelComponent( const Vector2 & vel ); + + /*! + * @brief Sets the constant velocity. + * + * @param velocity The velocity for this velocity component. + */ + void setVelocity( const Vector2 & velocity ); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Returns the constant velocity. + * + * @returns The velocity computed by this constant velocity component. + */ + Vector2 getConstVelocity() const { return _dir * _speed; } + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + friend class ConstVCFactory; + protected: + /*! + * @brief The direction of the constant preferred velocity. + */ + Vector2 _dir; + + /*! + * @brief The speed of the constant preferred velocity. + */ + float _speed; + }; + + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the ConstVelComponent. + */ + class MENGE_API ConstVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + ConstVCContext( ConstVelComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief The underlying finite state machine velocity component. + */ + ConstVelComponent * _vc; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ConstVelComponent. + */ + class MENGE_API ConstVCFactory : public VelCompFactory { + public: + /*! + * @brief Constructor. + */ + ConstVCFactory(); + + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "const"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is always a constant value (direction and magnitude)."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new ConstVelComponent(); } + + /*! + * @brief Given a pointer to an VelComponent instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelComponent's type. + * (i.e. VelCompFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelCompFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vc A pointer to the velocity component whose attributes are to be set. + * @param node The XML node containing the velocity component attributes. + * @param behaveFldr The path to the behavior file. If the velocity component references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "x" float attribute. + */ + size_t _xID; + + /*! + * @brief The identifier for the "y" float attribute. + */ + size_t _yID; + }; + + ///////////////////////////////////////////////////////////////////// + + // forward declaration + class ConstDirVCContext; + + /*! + * @brief A velocity component that always returns a constant direction but + * leaves the preferred speed unchanged. + */ + class MENGE_API ConstVelDirComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + ConstVelDirComponent(); + + /*! + * @brief Constructor. + * + * @param vel The preferred velocity direction to return (vel is *not* + * assumed to be unit-length). + */ + ConstVelDirComponent( const Vector2 & vel ); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Sets the direction of the velocity component. + * + * @param dir The direction the velocity should provide. + * The input need not be normalized, as tha will be done + * by this function. + */ + void setDirection( const Vector2 & dir ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + friend class ConstDirVCContext; + protected: + /*! + * @brief The direction of the constant preferred velocity. + */ + Vector2 _dir; + }; + + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the ConstVelDirComponent. + */ + class MENGE_API ConstDirVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + ConstDirVCContext( ConstVelDirComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief The underlying finite state machine velocity component. + */ + ConstVelDirComponent * _vc; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ConstVelDirComponent. + */ + class MENGE_API ConstDirVCFactory : public VelCompFactory { + public: + /*! + * @brief Constructor. + */ + ConstDirVCFactory(); + + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "const_dir"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is always in a fixed direction but uses the agent's preferred speed."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new ConstVelDirComponent(); } + + /*! + * @brief Given a pointer to an VelComponent instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelComponent's type. + * (i.e. VelCompFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelCompFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vc A pointer to the velocity component whose attributes are to be set. + * @param node The XML node containing the velocity component attributes. + * @param behaveFldr The path to the behavior file. If the velocity component references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "x" float attribute. + */ + size_t _xID; + + /*! + * @brief The identifier for the "y" float attribute. + */ + size_t _yID; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief A velocity component that always returns the zero velocity. + */ + class MENGE_API ZeroVelComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + ZeroVelComponent(); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the ZeroVelComponent. + */ + class MENGE_API ZeroVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + */ + ZeroVCContext(); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ZeroVelComponent. + */ + class MENGE_API ZeroVCFactory : public VelCompFactory { + public: + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "zero"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is always the zero velocity."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new ZeroVelComponent(); } + }; + + ////////////////////////////////////////////////////////////////////////////// + + } // namespace BFSM + +} // namespace Menge + +#endif // __VEL_COMP_CONST_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.cpp new file mode 100644 index 00000000..5bb170d8 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.cpp @@ -0,0 +1,155 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelCompContext.h" +#include "BaseAgent.h" +#include "PrefVelocity.h" +#include "VelComponent.h" +#include "shapes.h" +#include "Goals/Goal.h" +#include +#include "TextWriter.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VelCompContext + ///////////////////////////////////////////////////////////////////// + + std::string VelCompContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "No context defined"; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void VelCompContext::drawPrefVel( const Agents::PrefVelocity & pVel, const Vector2 & pos, float elevation ) { + + glPushAttrib( GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT ); + glDepthMask( GL_FALSE ); + glDisable( GL_DEPTH_TEST ); + const float length = pVel.getSpeed(); + glLineWidth( 2.f ); + if ( pVel.hasArea() ) { + // draw solid angle + // Display contraction normal + const Vector2 & left = pVel.getLeft(); + const Vector2 & right = pVel.getRight(); + float theta = acos( left * right ); + + glColor3f( 0.2f, 1.0f, 0.2f ); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + + float sTheta = atan2( right.y(), right.x() ); + const int SAMPLES = int( theta / (5.f * DEG_TO_RAD ) + 0.5f ); + const float dTheta = theta / SAMPLES; + glPushMatrix(); + glTranslatef( pos.x(), elevation, pos.y() ); + glScalef( length, length, length ); + glBegin( GL_POLYGON ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( right.x(), 0.f, right.y() ); + for ( int i = 1; i <= SAMPLES; ++i ) { + float angle = sTheta + i * dTheta; + float x = cos( angle ); + float y = sin( angle ); + glVertex3f( x, 0.f, y ); + } + glEnd(); + + glPopMatrix(); + } + + // draw preferred direction + Vector2 dir( pVel.getPreferred() ); + glPushMatrix(); + glTranslatef( pos.x(), elevation, pos.y() ); + float angle = atan2( -dir.y(), dir.x() ) * RAD_TO_DEG; + glRotatef( angle, 0.f, 1.f, 0.f ); + glColor3f( 1.f, 0.25f, 0.25f ); + glLineWidth( 3.f ); + const float SIZE = 0.1f; + const float HALF_SIZE = SIZE * 0.5f; + glBegin( GL_LINE_STRIP ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( length - SIZE, 0.f, 0.f ); + glVertex3f( length - SIZE, 0.f, -HALF_SIZE ); + glVertex3f( length, 0.f, 0.f ); + glVertex3f( length - SIZE, 0.f, HALF_SIZE ); + glVertex3f( length - SIZE, 0.f, 0.f ); + glEnd(); + glPopMatrix(); + + // draw target point + glPointSize( 5.f ); + glColor3f( 0.3f, 1.f, 1.f ); + glBegin( GL_POINTS ); + glVertex3f( pVel.getTarget()._x, elevation, pVel.getTarget()._y ); + glEnd(); + glPopAttrib(); + } + + ///////////////////////////////////////////////////////////////////// + + void VelCompContext::drawGoal( const Vector2 & goalPoint, const Agents::BaseAgent * agent ) const { + drawGoal( Vector3( goalPoint.x(), 0.f, goalPoint.y() ), agent->_radius ); + } + + ///////////////////////////////////////////////////////////////////// + + void VelCompContext::drawGoal( const Vector3 & goalPoint, float agtRadius ) const { + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glDepthMask( GL_FALSE ); + glPushMatrix(); + const float R = agtRadius / 5.f; + glTranslatef( goalPoint.x(), goalPoint.y(), goalPoint.z() ); + SceneGraph::Circle::drawCircle( R * 5.f, 1.f, 0.f, 0.f, 1.f ); + SceneGraph::Circle::drawCircle( R * 4.f, 1.f, 1.f, 1.f, 1.f ); + SceneGraph::Circle::drawCircle( R * 3.f, 1.f, 0.f, 0.f, 1.f ); + SceneGraph::Circle::drawCircle( R * 2.f, 1.f, 1.f, 1.f, 1.f ); + SceneGraph::Circle::drawCircle( R * 1.f, 1.f, 0.f, 0.f, 1.f ); + glPopMatrix(); + glPopAttrib(); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.h new file mode 100644 index 00000000..1ac194b3 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompContext.h @@ -0,0 +1,151 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompContext.h + * @brief The definition of a basic UI context for finite + * state machine *velocity components*. + */ + +#ifndef __VEL_COMP_CONTEXT_H__ +#define __VEL_COMP_CONTEXT_H__ + +#include "Context.h" +#include + +namespace Menge { + + namespace Agents { + class BaseAgent; + class PrefVelocity; + } + + namespace BFSM { + + // Forward declarations + class VelComponent; + class Goal; + + /*! + * @brief Base context for finite state machine velocity components. + * + * This differs from the standard scene graph context by being + * dependent on an input agent. + */ + class MENGE_API VelCompContext : public SceneGraph::Context { + public: + /*! + * @brief Constructor. + */ + VelCompContext(){} + + /*! + * @brief This supplants the destructor. + * + * In order to preserve potential problems in windows when + * dlls do not share the same c-runtime library, the destructor + * is held to be private. To garbage collect an VelComponent, + * the destroy method should be called (which in turn, will call + * the destructor from its own memory space, averting run-time + * crashes). + * + * Once this has been called, the VelComponent no longer exists. Calling + * methods or accessing members will produce indetermine behavior + * (most likely errors). + */ + void destroy() { delete this; } + + protected: + /*! + * @brief Destructor. + */ + virtual ~VelCompContext(){} + + public: + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ){} + + protected: + /*! + * @brief Draws the preferred velocity in a consistent way + * + * @param pVel The preferred velocity of the agent computed by the vel component. + * @param pos The position of the velocity vector's origin. + * @param elevation The optional elevation of the velocity. + */ + void drawPrefVel( const Agents::PrefVelocity & pVel, const Vector2 & pos, float elevation=0.f ); + + /*! + * @brief Draws the 2d goal point in a consistent manner + * + * @param goalPoint The position of the agent's goal + * @param agent The agent + */ + void drawGoal( const Vector2 & goalPoint, const Agents::BaseAgent * agent ) const; + + /*! + * @brief Draws the 3d goal point in a consistent manner + * + * @param agtRadius The agent's radius + * @param goalPoint The position of the goal + */ + void drawGoal( const Vector3 & goalPoint, float agtRadius=0.19f ) const; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __VEL_COMP_CONTEXT_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.cpp new file mode 100644 index 00000000..d3d332a0 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.cpp @@ -0,0 +1,121 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityComponents/VelCompGoal.h" +#include "BaseAgent.h" +#include "PrefVelocity.h" +#include "Goals/Goal.h" +#include "Core.h" + +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalVelComponent + ///////////////////////////////////////////////////////////////////// + + GoalVelComponent::GoalVelComponent(): VelComponent() { + } + + ///////////////////////////////////////////////////////////////////// + + void GoalVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + // directions + goal->setDirections( agent->_pos, agent->_radius, pVel ); + + // speed + Vector2 goalPoint = pVel.getTarget(); + Vector2 disp = goalPoint - agent->_pos; + const float distSq = absSq( disp ); + float speed = agent->_prefSpeed; + + if ( distSq <= 0.0001f ) { + // I've basically arrived -- speed should be zero. + speed = 0.f; + } else { + const float speedSq = speed * speed; + const float TS_SQD = SIM_TIME_STEP * SIM_TIME_STEP; + if ( distSq / speedSq < TS_SQD ) { + // The distance is less than I would travel in a single time step. + speed = sqrtf( distSq ) / SIM_TIME_STEP; + } + } + pVel.setSpeed( speed ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * GoalVelComponent::getContext() { + return new GoalVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of GoalVCContext + ///////////////////////////////////////////////////////////////////// + + GoalVCContext::GoalVCContext( GoalVelComponent * vc ):VelCompContext(),_vc(vc) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string GoalVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Goal velocity component"; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void GoalVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + // draw goal point + // TODO: Get the elevation of the goalPoint + Vector2 goalPoint = goal->getTargetPoint( agt->_pos, agt->_radius ); + drawGoal( goalPoint, agt ); + + // draw preferred velocity + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.h new file mode 100644 index 00000000..7666cf2c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompGoal.h @@ -0,0 +1,183 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompGoal.h + * @brief Provides the definition of the simple velocity component + * that computes a preferred velocity directly towards the goal. + */ + +#ifndef __VEL_COMP_GOAL_H__ +#define __VEL_COMP_GOAL_H__ + +#include "CoreConfig.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelCompContext.h" + +namespace Menge { + + namespace BFSM { + + /*! + * @brief A velocity component that returns a preferred velocity whose direction + * points from the current agent position toward the goal point. + */ + class MENGE_API GoalVelComponent: public VelComponent { + public: + /*! + * @brief Default constructor. + */ + GoalVelComponent(); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the GoalVelComponent. + */ + class MENGE_API GoalVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + GoalVCContext( GoalVelComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief The underlying finite state machine velocity component. + */ + GoalVelComponent * _vc; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the GoalVelComponent. + */ + class MENGE_API GoalVCFactory : public VelCompFactory { + public: + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "goal"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which always aims directly toward the goal (at the agent's preferred speed)"\ + " unless it will overstep the goal in a single time step, then it is scaled down."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new GoalVelComponent(); } + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __VEL_COMP_GOAL_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.cpp new file mode 100644 index 00000000..87c79707 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.cpp @@ -0,0 +1,385 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityComponents/VelCompNavMesh.h" +#include "Tasks/NavMeshLocalizerTask.h" +#include "NavMeshNode.h" +#include "NavMeshEdge.h" +#include "BaseAgent.h" +#include "os.h" +#include "Logger.h" +#include "PathPlanner.h" +#include "PortalPath.h" +#include "Route.h" +#include "Goals/Goal.h" + +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshVelComponent + ///////////////////////////////////////////////////////////////////// + + NavMeshVelComponent::NavMeshVelComponent():VelComponent(),_headingDevCos(-1.f),_navMesh(0x0),_localizer(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshVelComponent::onExit( Agents::BaseAgent * agent ) { + _localizer->clearPath( agent->_id ); + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshVelComponent::setHeadingDeviation( float angle ) { + _headingDevCos = cos( angle ); + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + // If agent does not have a path + PortalPath * path = _localizer->getPath( agent->_id ); + if ( path == 0x0 ) { + // Get the route + Vector2 goalPoint = goal->getCentroid(); + unsigned int goalNode = _localizer->getNode( goalPoint ); + if ( goalNode == NavMeshLocation::NO_NODE ) { + throw VelCompFatalException( "Can't compute a path to a goal outside of the navigation mesh. Bad NavMeshVelComponent!" ); + } + unsigned int agtNode = _localizer->getNode( agent ); + PortalRoute * route = _localizer->getPlanner()->getRoute( agtNode, goalNode, agent->_radius * 2.f ); + // compute the path + path = new PortalPath( agent->_pos, goal, route, agent->_radius ); + // assign it to the localizer + _localizer->setPath( agent->_id, path ); + } + pVel.setSpeed( agent->_prefSpeed ); + path->setPreferredDirection( agent, _headingDevCos, pVel ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * NavMeshVelComponent::getContext() { + return new NavMeshVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * NavMeshVelComponent::getTask() { + return new NavMeshLocalizerTask( _navMesh->getName(), true /*usePlanner*/ ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshVCContext + ///////////////////////////////////////////////////////////////////// + + NavMeshVCContext::NavMeshVCContext( NavMeshVelComponent * vc ):VelCompContext(),_vc(vc),_drawCenters(false),_drawNodeIDs(false) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string NavMeshVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Navigation mesh velocity component"; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + const NavMeshPtr navMesh = _vc->_navMesh; + ss << "\n" << indent << " Num. vertices: " << navMesh->getVertexCount(); + ss << "\n" << indent << " Num. polygons: " << navMesh->getNodeCount(); + ss << "\n" << indent << " Num. edges: " << navMesh->getEdgeCount(); + if ( _drawCenters ) { + ss << "\n" << indent << " Hide polygon (Ctrl-c)enters"; + } else { + ss << "\n" << indent << " Draw polygon (Ctrl-c)enters"; + } + if ( _drawNodeIDs ) { + ss << "\n" << indent << " Hide polygon (Ctrl-i)ds"; + } else { + ss << "\n" << indent << " Draw polygon (Ctrl-i)ds"; + } + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult NavMeshVCContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result( false, false ); + + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + + if ( e.type == SDL_KEYDOWN ) { + if ( hasCtrl && !hasAlt && !hasShift ) { + if ( e.key.keysym.sym == SDLK_c ) { + _drawCenters = !_drawCenters; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_i ) { + _drawNodeIDs = ! _drawNodeIDs; + result.set( true, true ); + } + } + } + + return result; + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + getOpenGLView(); + drawNavMesh(); + drawPath( agt, goal ); + + // draw the preferred velocity + NavMeshPtr navMesh = _vc->getLocalizer()->getNavMesh(); + unsigned int NODE_ID = _vc->getLocalizer()->getNode( agt ); + float elevation = navMesh->getElevation( NODE_ID, agt->_pos ); + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos, elevation ); + } + + //////////////////////////////////////////////////////////////////////////// + + void NavMeshVCContext::drawNavMesh() const { + const NavMeshPtr navMesh = _vc->_navMesh; + unsigned int nCount = static_cast< unsigned int >( navMesh->getNodeCount() ); + + const Vector2 * vertices = navMesh->getVertices(); + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POINT_BIT | GL_DEPTH_BUFFER_BIT ); + + // shaded regions + glDepthMask( GL_FALSE ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f( 0.5f, 0.8f, 1.f, 0.25f ); + for ( unsigned int n = 0; n < nCount; ++n ) { + const NavMeshNode & node = navMesh->getNode( n ); + size_t vCount = node.getVertexCount(); + glBegin( GL_POLYGON ); + for ( size_t v = 0; v < vCount; ++ v ) { + unsigned int vID = node.getVertexID( v ); + const Vector2 & p = vertices[ vID ]; + float elevation = node.getElevation( p ); + glVertex3f( p.x(), elevation, p.y() ); + } + glEnd(); + } + + // outlines + glDisable( GL_BLEND ); + // edges + unsigned int eCount = static_cast< unsigned int >( navMesh->getEdgeCount() ); + glBegin( GL_LINES ); + for ( unsigned int e = 0; e < eCount; ++e ) { + const NavMeshEdge & edge = navMesh->getEdge( e ); + const NavMeshNode * node = edge.getFirstNode(); + Vector2 p0 = edge.getP0(); + float h = node->getElevation( p0 ); + glVertex3f( p0.x(), h, p0.y() ); + Vector2 p1 = edge.getP1(); + h = node->getElevation( p1 ); + glVertex3f( p1.x(), h, p1.y() ); + } + glEnd(); + + + if ( _drawCenters ) { + //centers + glPushAttrib( GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_POINT_BIT ); + glDepthMask( GL_FALSE ); + glDisable( GL_DEPTH_TEST ); + glPointSize( 5.f ); + glBegin( GL_POINTS ); + for ( unsigned int n = 0; n < nCount; ++n ) { + const NavMeshNode & node = navMesh->getNode( n ); + Vector2 p = node.getCenter(); + float elevation = node.getElevation( p ); + glVertex3f( p.x(), elevation, p.y() ); + } + glEnd(); + glPopAttrib(); + } + + if ( _drawNodeIDs ) { + drawNodeIDs(); + } + + // obstacles + glColor3f( 1.f, 0.1f, 0.1f ); + unsigned int oCount = static_cast< unsigned int >( navMesh->getObstacleCount() ); + glBegin( GL_LINES ); + for ( unsigned int o = 0; o < oCount; ++o ) { + const NavMeshObstacle & obst = navMesh->getObstacle( o ); + const NavMeshNode * node = obst.getNode(); + Vector2 p0 = obst.getP0(); + float h = node->getElevation( p0 ); + glVertex3f( p0.x(), h, p0.y() ); + Vector2 p1 = obst.getP1(); + h = node->getElevation( p1 ); + glVertex3f( p1.x(), h, p1.y() ); + } + glEnd(); + + glPopAttrib(); + } + + //////////////////////////////////////////////////////////////////////////// + + void NavMeshVCContext::drawPath( const Agents::BaseAgent * agt, const Goal * goal ) const { + + const size_t ID = agt->_id; + PortalPath * path = _vc->getLocalizer()->getPath( ID ); + if ( path ) { + NavMeshPtr navMesh = _vc->getNavMesh(); + unsigned int NODE_ID = _vc->getLocalizer()->getNode( agt ); + Vector2 prev( agt->_pos ); + float height = navMesh->getElevation( NODE_ID, prev ); + glPushAttrib( GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT ); + glDepthMask( GL_FALSE ); + + glColor3f( 1.f, 1.f, 0.f ); + glLineWidth( 3.f ); + glBegin( GL_LINE_STRIP ); + glVertex3f( prev.x(), height, prev.y() ); + // iterate through the rest + const size_t P_COUNT = path->getWayPointCount(); + size_t i = path->getCurrentPortal(); + if ( i < P_COUNT ) { + NODE_ID = path->getNode( i ); + prev.set( path->getWayPoint( i ) ); + height = navMesh->getElevation( NODE_ID, prev ); + ++i; + } + Vector2 p; + for ( ; i < P_COUNT; ++i ) { + NODE_ID = path->getNode( i ); + p.set( path->getWayPoint( i ) ); + float h = navMesh->getElevation( NODE_ID, p ); + if ( absSq( p - prev ) > 0.001f ) { + glVertex3f( prev.x(), height, prev.y() ); + } + prev.set( p ); + height = h; + } + glVertex3f( prev.x(), height, prev.y() ); + + const BFSM::Goal * goal = path->getGoal(); + Vector2 goalPoint = goal->getTargetPoint( prev, agt->_radius ); + height = navMesh->getElevation( path->getEndNode(), goalPoint ); + glVertex3f( goalPoint.x(), height, goalPoint.y() ); + + glEnd(); + glPopAttrib(); + + // draw goal + Vector3 goal3D( goalPoint.x(), height, goalPoint.y() ); + drawGoal( goal3D, agt->_radius ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void NavMeshVCContext::drawNodeIDs() const { + const NavMeshPtr navMesh = _vc->_navMesh; + unsigned int nCount = static_cast< unsigned int >( navMesh->getNodeCount() ); + + glColor4f( 0.5f, 0.8f, 1.f, 1.f ); + for ( unsigned int n = 0; n < nCount; ++n ) { + std::stringstream ss; + ss << n; + const NavMeshNode & node = navMesh->getNode( n ); + Vector3 p = node.getCenter3D(); + writeText( ss.str(), p, true/*currColor*/ ); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshVCFactory + ///////////////////////////////////////////////////////////////////// + + NavMeshVCFactory::NavMeshVCFactory() : VelCompFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + _headingID = _attrSet.addFloatAttribute( "heading_threshold", false /*required*/, 180.f ); + } + + ///////////////////////////////////////////////////////////////////// + + bool NavMeshVCFactory::setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const { + NavMeshVelComponent * nmvc = dynamic_cast< NavMeshVelComponent * >( vc ); + assert( nmvc != 0x0 && "Trying to set attributes of a navigation mesh velocity component on an incompatible object" ); + + if ( ! VelCompFactory::setFromXML( nmvc, node, behaveFldr ) ) return false; + + // get the absolute path to the file name + + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + NavMeshPtr nmPtr; + try { + nmPtr = loadNavMesh( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh referenced on line " << node->Row() << "."; + return false; + } + nmvc->setNavMesh( nmPtr ); + // nav mesh localizer + NavMeshLocalizerPtr nmlPtr; + try { + nmlPtr = loadNavMeshLocalizer( fName, true ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the navigation mesh localizer required by the velocity component on line " << node->Row() << "."; + return false; + } + nmvc->setNavMeshLocalizer( nmlPtr ); + nmvc->setHeadingDeviation( _attrSet.getFloat( _headingID ) * DEG_TO_RAD ); + + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.h new file mode 100644 index 00000000..8397e620 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompNavMesh.h @@ -0,0 +1,337 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompNavMesh.h + * @brief Provides the definition of the navigation mesh velocity component. + * The preferred velocity is defined for each agent based on a + * polygonal mesh representation of the free space (a navigation mesh) + * and searches on that graph. + */ + +#ifndef __VEL_COMP_NAV_MESH_H__ +#define __VEL_COMP_NAV_MESH_H__ + +#include "CoreConfig.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelCompContext.h" +#include "NavMesh.h" +#include "NavMeshLocalizer.h" + +// forward declaration + +namespace Menge { + + namespace BFSM { + // forward declaration + class NavMeshVCContext; + + /*! + * @brief A velocity component that returns a preferred velocity whose direction + * and preferred speed are computed from a navigation mesh. + * + * A navigation mesh is a representation of the traversalbe space. The traversable space + * is represented as a polygonal mesh. Graph searches through the mesh are performed to + * find paths through arbitrarily complex environments. + */ + class MENGE_API NavMeshVelComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + NavMeshVelComponent(); + + /*! + * @brief Called when the agent exits the state that uses this velocity component. + * + * @param agent The agent exiting the state. + */ + virtual void onExit( Agents::BaseAgent * agent ); + + /*! + * @brief Sets the navigation mesh pointer. + * + * @param nm The managed pointer to the navigation mesh. + */ + void setNavMesh( const NavMeshPtr & nm ) { _navMesh = nm; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh + * + * @returns The navigation mesh. + */ + NavMeshPtr getNavMesh() { return _navMesh; } + + /*! + * @brief Returns a resource pointer to the underlying navigation mesh localizer + * + * @returns The navigation mesh localizer. + */ + NavMeshLocalizerPtr getLocalizer() { return _localizer; } + + /*! + * @brief Sets the navigation mesh localizer pointer. + * + * @param nml The managed pointer to the navigation mesh localizer. + */ + void setNavMeshLocalizer( const NavMeshLocalizerPtr & nml ) { _localizer = nml; } + + /*! + * @brief Sets the angular deviation which triggers replanning. + * + * @param angle The angle of deviation in radians. + */ + void setHeadingDeviation( float angle ); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + /*! + * @brief Returns a pointer to the nav mesh localizer task. + * + * @returns A pointer to the nav mesh localizer task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual Task * getTask(); + + friend class NavMeshVCContext; + + protected: + /*! + * @brief The cosine of the heading deviation angular threshold. This detects + * when the angle of approach deviates beyond a threshold and the agent + * needs to replan. + */ + float _headingDevCos; + + /*! + * @brief The navigation mesh. + */ + NavMeshPtr _navMesh; + + /*! + * @brief The localizer for the navigation mesh. + */ + NavMeshLocalizerPtr _localizer; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the NavMeshVelComponent. + */ + class MENGE_API NavMeshVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + NavMeshVCContext( NavMeshVelComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief Draws the navigation mesh to the 3D context based on current settings. + */ + void drawNavMesh() const; + + /*! + * @brief Draws the path for the selected agent. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + void drawPath( const Agents::BaseAgent * agt, const Goal * goal ) const; + + /*! + * @brief Draws the ids on the polygon mesh centers. + */ + void drawNodeIDs() const; + + /*! + * @brief The underlying finite state machine velocity component. + */ + NavMeshVelComponent * _vc; + + /*! + * @brief Visualization flag - controls if polygon centers are drawn. + */ + bool _drawCenters; + + /*! + * @brief Visualizaton flag - controls if polygon ids are drawn. + */ + bool _drawNodeIDs; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the NavMeshVelComponent. + */ + class MENGE_API NavMeshVCFactory : public VelCompFactory { + public: + /*! + * @brief Constructor. + */ + NavMeshVCFactory(); + + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "nav_mesh"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is derived from a path along a "\ + "polygonally decomposed representation of the traversable space (a navigaiton mesh)."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new NavMeshVelComponent(); } + + /*! + * @brief Given a pointer to an VelComponent instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelComponent's type. + * (i.e. VelCompFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelCompFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vc A pointer to the velocity component whose attributes are to be set. + * @param node The XML node containing the velocity component attributes. + * @param behaveFldr The path to the behavior file. If the velocity component references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + + /*! + * @brief The identifier for the "heading_threshold" float attribute. + */ + size_t _headingID; + }; + } // namespace BFSM +} // namespace Menge +#endif // __VEL_COMP_NAV_MESH_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.cpp new file mode 100644 index 00000000..111a2f9c --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.cpp @@ -0,0 +1,252 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityComponents/VelCompRoadMap.h" +#include "BaseAgent.h" +#include "os.h" +#include "Graph.h" +#include "Goals/Goal.h" + +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of RoadMapVelComponent + ///////////////////////////////////////////////////////////////////// + + RoadMapVelComponent::RoadMapVelComponent():VelComponent(), _roadmap(0x0) { + } + + ///////////////////////////////////////////////////////////////////// + + RoadMapVelComponent::RoadMapVelComponent( const GraphPtr & graph ):VelComponent(), _roadmap(graph) { + } + + ///////////////////////////////////////////////////////////////////// + + RoadMapVelComponent::~RoadMapVelComponent() { + PathMap::iterator itr = _paths.begin(); + for ( ; itr != _paths.end(); ++itr ) { + delete itr->second; + } + _paths.clear(); + } + + ///////////////////////////////////////////////////////////////////// + + void RoadMapVelComponent::onExit( Agents::BaseAgent * agent ) { + // This test is necessary. Because state advancement can jump MULTIPLE states in a single + // time step, it is possible to enter and exit a state with a roadmap velocity without + // ever actually calling "setPrefVelocity" on that velocity component. + // + // Roadmap initializes the path in setPrefVelocity - so, things don't get properly + // initialized. + _lock.lockWrite(); + PathMap::iterator itr = _paths.find( agent->_id ); + if ( itr != _paths.end() ) { + delete itr->second; + _paths.erase( agent->_id ); + } + _lock.releaseWrite(); + } + + ///////////////////////////////////////////////////////////////////// + + void RoadMapVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + _lock.lockRead(); + PathMap::iterator itr = _paths.find( agent->_id ); + RoadMapPath * path = 0x0; + if ( itr == _paths.end() ) { + _lock.releaseRead(); + // compute the path and add it to the map + // Create path for the agent + Vector2 goalPoint = goal->getCentroid(); + path = _roadmap->getPath( agent, goal ); + _lock.lockWrite(); + _paths[ agent->_id ] = path; + _lock.releaseWrite(); + } else { + path = itr->second; + _lock.releaseRead(); + } + pVel.setSpeed( agent->_prefSpeed ); + path->setPrefDirection( agent, pVel ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * RoadMapVelComponent::getContext() { + return new RoadMapVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of RoadMapVCContext + ///////////////////////////////////////////////////////////////////// + + RoadMapVCContext::RoadMapVCContext( RoadMapVelComponent * vc ):VelCompContext(),_vc(vc) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string RoadMapVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Roadmap velocity component"; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void RoadMapVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + // draw target + glPushAttrib( GL_POINT_BIT | GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glDepthMask( GL_FALSE ); + + GraphPtr & graph = _vc->_roadmap; + + // draw edges + glColor3f( 0.2f, 0.2f, 1.f ); + glLineWidth( 1.5f ); + glBegin( GL_LINES ); + const size_t V_COUNT = graph->getVertexCount(); + for ( size_t i = 0; i < V_COUNT; ++i ) { + const GraphVertex * v = graph->getVertex( i ); + const size_t vID = v->getID(); + const Vector2 vPos = v->getPosition(); + const size_t N_COUNT = v->getNeighborCount(); + for ( size_t j = 0; j < N_COUNT; ++j ) { + const GraphVertex * u = v->getNeighbor( j ); + if ( vID < u->getID() ) { + glVertex3f( vPos.x(), 0.f, vPos.y() ); + Vector2 uPos = u->getPosition(); + glVertex3f( uPos.x(), 0.f, uPos.y() ); + } + } + } + glEnd(); + + // draw nodes + glColor3f( 1.0f, 0.6f, 1.f ); + glPointSize( 5.f ); + glBegin( GL_POINTS ); + for ( size_t i = 0; i < V_COUNT; ++i ) { + const GraphVertex * v = graph->getVertex( i ); + const Vector2 vPos = v->getPosition(); + glVertex3f( vPos.x(), 0.f, vPos.y() ); + } + glEnd(); + + // draw path + Vector2 tgtPoint; + PathMap::iterator itr = _vc->_paths.find( agt->_id ); + if ( itr != _vc->_paths.end() ) { + const RoadMapPath * path = itr->second; + const size_t WP_COUNT = path->getWayPointCount(); + + // draw the goal + if ( WP_COUNT > 0 ) { + // nearest point to the goal from the last way point + tgtPoint = goal->getTargetPoint( path->getWayPoint( WP_COUNT - 1 ), agt->_radius ); + } else { + tgtPoint = goal->getTargetPoint( agt->_pos, agt->_radius ); + } + + const size_t TARGET = path->getTargetID(); + glColor3f( 1.f, 1.f, 0.5f ); + glLineWidth( 2.f ); + glBegin( GL_LINE_STRIP ); + glVertex3f( agt->_pos.x(), 0.f, agt->_pos.y() ); + for ( size_t i = TARGET; i < WP_COUNT; ++i ) { + Vector2 p = path->getWayPoint( i ); + glVertex3f( p.x(), 0.f, p.y() ); + } + glVertex3f( tgtPoint.x(), 0.f, tgtPoint.y() ); + glEnd(); + } else { + tgtPoint = goal->getTargetPoint( agt->_pos, agt->_radius ); + } + + // draw goal + // TODO: REALLY draw the goal + drawGoal( tgtPoint, agt ); + + // draw the preferred velocity + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos ); + + glPopAttrib(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of RoadMapVCFactory + ///////////////////////////////////////////////////////////////////// + + RoadMapVCFactory::RoadMapVCFactory() : VelCompFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool RoadMapVCFactory::setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const { + RoadMapVelComponent * rmvc = dynamic_cast< RoadMapVelComponent * >( vc ); + assert( rmvc != 0x0 && "Trying to set attributes of a road map velocity component on an incompatible object" ); + + if ( ! VelCompFactory::setFromXML( rmvc, node, behaveFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + GraphPtr gPtr; + try { + gPtr = loadGraph( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the road map referenced on line " << node->Row() << "."; + return false; + } + rmvc->setRoadMap( gPtr ); + + return true; + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.h new file mode 100644 index 00000000..0d601474 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompRoadMap.h @@ -0,0 +1,280 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompRoadMap.h + * @brief Provides the definition of the road map velocity component. + * The preferred velocity is defined for each agent based on a + * discrete graph reprsentation of the free space (a roadmap) + * and searches on that graph. + */ + +#ifndef __VEL_COMP_ROAD_MAP_H__ +#define __VEL_COMP_ROAD_MAP_H__ + +#include "CoreConfig.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelCompContext.h" +#include +#include "Graph.h" +#include "RoadMapPath.h" +#include "ReadersWriterLock.h" + +namespace Menge { + + // forward declaration + template < class R > + class ResourcePtr; + + /*! + * @brief forward declaration of graph resource pointer. + * see graph.h for more details + */ + typedef ResourcePtr< Graph > GraphPtr; + + namespace BFSM { + // forward declaration + class RoadMapVCContext; + + /*! + * @brief A velocity component that returns a preferred velocity whose direction + * and preferred speed are computed from a velocity field. + * + * If the velocity vector is of unit length, the preferred speed will be unchanged. + * Otherwise, the preferred speed is scaled by the length of the velocity vector. + */ + class MENGE_API RoadMapVelComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + RoadMapVelComponent(); + + /*! + * @brief Constructor. + * + * @param graph The graph representing the roadmap. + * The graph will be destroyed when the velocity component + * is destroyed. + */ + RoadMapVelComponent( const GraphPtr & graph ); + + /*! + * @brief Destructor. + */ + ~RoadMapVelComponent(); + + /*! + * @brief Sets the road map for this velocity component. + * + * @param graph The graph of the roadmap. + */ + void setRoadMap( const GraphPtr & graph ) { _roadmap = graph; } + + /*! + * @brief Called when the agent leaves the state which possesses this velocity component. + * + * Gives the velocity component to restore any agent-specific data it might have changed. + * + * @param agent The agent who left the state. + */ + virtual void onExit( Agents::BaseAgent * agent ); + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + friend class RoadMapVCContext; + + protected: + /*! + * @brief The roadmap. + */ + GraphPtr _roadmap; + + /*! + * @brief The paths for all agents in this state. + */ + PathMap _paths; + + /*! + * @brief Lock to protect _paths; + */ + ReadersWriterLock _lock; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the RoadMapVelComponent. + */ + class MENGE_API RoadMapVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + RoadMapVCContext( RoadMapVelComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief The underlying finite state machine velocity component. + */ + RoadMapVelComponent * _vc; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the RoadMapVelComponent. + */ + class MENGE_API RoadMapVCFactory : public VelCompFactory { + public: + /*! + * @brief Constructor. + */ + RoadMapVCFactory(); + + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "road_map"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is derived from a path along a "\ + "graph discretization of the free space (a.k.a. a road map)."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new RoadMapVelComponent(); } + + /*! + * @brief Given a pointer to an VelComponent instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelComponent's type. + * (i.e. VelCompFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelCompFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vc A pointer to the velocity component whose attributes are to be set. + * @param node The XML node containing the velocity component attributes. + * @param behaveFldr The path to the behavior file. If the velocity component references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; + } // namespace BFSM +} // namespace Menge +#endif // __VEL_COMP_ROAD_MAP_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.cpp new file mode 100644 index 00000000..9219720d --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.cpp @@ -0,0 +1,261 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityComponents/VelCompVF.h" +#include "BaseAgent.h" +#include "os.h" +#include "Logger.h" +#include "Goals/Goal.h" + +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VFVelComponent + ///////////////////////////////////////////////////////////////////// + + VFVelComponent::VFVelComponent(): VelComponent(), _vf(0x0), _nearest(true) { + } + + ///////////////////////////////////////////////////////////////////// + + VFVelComponent::VFVelComponent( VectorFieldPtr & vf, bool useNearest ): VelComponent(), _vf(vf), _nearest(useNearest) { + } + + ///////////////////////////////////////////////////////////////////// + + void VFVelComponent::setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) { + Vector2 dir; + if ( _nearest ) { + dir.set( _vf->getFieldValue( agent->_pos ) ); + } else { + dir.set( _vf->getFieldValueInterp( agent->_pos ) ); + } + + float scale = abs( dir ); + float speed = agent->_prefSpeed * scale; + + if ( scale > EPS ) { + pVel.setSingle( dir / scale ); + pVel.setSpeed( speed ); + } else { + pVel.setSingle( Vector2( 1.f, 0.f ) ); + pVel.setSpeed( 0.f ); + } + pVel.setTarget( pVel.getPreferredVel() * 5.f + agent->_pos ); + } + + ///////////////////////////////////////////////////////////////////// + + VelCompContext * VFVelComponent::getContext() { + return new VecFieldVCContext( this ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of VecFieldVCContext + ///////////////////////////////////////////////////////////////////// + + VecFieldVCContext::VecFieldVCContext( VFVelComponent * vc ):VelCompContext(),_vc(vc),_showLocal(true), _neighborhood(5) { + } + + ///////////////////////////////////////////////////////////////////// + + std::string VecFieldVCContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Vector field velocity component"; + ss << "\n" << indent << " Toggle (Ctrl-L)ocal display"; + ss << "\n" << indent << " Neighborhood: " << _neighborhood << " cells (Ctrl-up/down to change)"; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult VecFieldVCContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result( false, false ); + + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + + if ( e.type == SDL_KEYDOWN ) { + if ( hasCtrl && !hasAlt && !hasShift ) { + if ( e.key.keysym.sym == SDLK_UP ) { + ++_neighborhood; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_DOWN ) { + --_neighborhood; + if ( _neighborhood <= 1 ) { + _neighborhood = 1; + } + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_l ) { + _showLocal = !_showLocal; + result.set( true, true ); + } + } + } + + return result; + } + + ///////////////////////////////////////////////////////////////////// + + void VecFieldVCContext::draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ) { + glPushAttrib( GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glDepthMask( GL_FALSE ); + // draw the grid + int rowZero = 0; + int lastRow = _vc->_vf->getRowCount(); + int colZero = 0; + int lastCol = _vc->_vf->getColCount(); + const float cellSize = _vc->_vf->getCellSize(); + Vector2 maxCorner = _vc->_vf->getMaximumPoint(); + Vector2 minCorner = _vc->_vf->getMinimumPoint(); + float left = minCorner.x(); + float right = maxCorner.x(); + float bottom = minCorner.y(); + float top = maxCorner.y(); + + if ( _showLocal ) { + int r, c; + _vc->_vf->getCell( agt->_pos, r, c ); + + rowZero = r - _neighborhood; + if ( rowZero < 0 ) rowZero = 0; + int tmp = r + _neighborhood + 1; + if ( tmp < lastRow ) lastRow = tmp; + + colZero = c - _neighborhood; + if ( colZero < 0 ) colZero = 0; + tmp = c + _neighborhood + 1; + if ( tmp < lastCol ) lastCol = tmp; + + left = minCorner.x() + colZero * cellSize; + bottom = minCorner.y() + rowZero * cellSize; + right = minCorner.x() + lastCol * cellSize; + top = minCorner.y() + lastRow * cellSize; + } + + glLineWidth( 1.f ); + glColor3f( 0.5f, 0.5f, 0.5f ); + glBegin( GL_LINES ); + // lines parallel w/ x-axis + for ( int r = rowZero; r <= lastRow; ++r ) { + float y = minCorner.y() + r * cellSize; + glVertex3f( left, 0.f, y ); + glVertex3f( right, 0.f, y ); + } + + // lines parallel w/ y-axis + for ( int c = colZero; c <= lastCol; ++c ) { + float x = minCorner.x() + c * cellSize; + glVertex3f( x, 0.f, bottom ); + glVertex3f( x, 0.f, top ); + } + glEnd(); + + // draw the vectors + float y = bottom + 0.5f * cellSize; + glColor3f( 1.f, 0.5f, 0.f ); + glBegin( GL_LINES ); + const float UNIT_SCALE = cellSize * 0.45f; + for ( int r = rowZero; r < lastRow; ++ r ) { + float x = left + 0.5f * cellSize; + for ( int c = colZero; c < lastCol; ++c ) { + Vector2 dir = _vc->_vf->getFieldValue( r, c ) * UNIT_SCALE; + Vector2 end( dir.x() + x, dir.y() + y ); + glVertex3f( x, 0.f, y ); + glVertex3f( end.x(), 0.f, end.y() ); + x += cellSize; + } + y += cellSize; + } + glEnd(); + + // TODO: draw the goal + + // draw the preferred velocity + Agents::PrefVelocity pVel; + _vc->setPrefVelocity( agt, goal, pVel ); + drawPrefVel( pVel, agt->_pos ); + + glPopAttrib(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of VFVCFactory + ///////////////////////////////////////////////////////////////////// + + VFVCFactory::VFVCFactory() : VelCompFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + _useNearestID = _attrSet.addBoolAttribute( "use_nearest", false /*required*/, true /*default*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool VFVCFactory::setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const { + VFVelComponent * vfvc = dynamic_cast< VFVelComponent * >( vc ); + assert( vfvc != 0x0 && "Trying to set attributes of a velocity field velocity component on an incompatible object" ); + + if ( ! VelCompFactory::setFromXML( vfvc, node, behaveFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + VectorFieldPtr vfPtr; + try { + vfPtr = loadVectorField( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the vector field referenced on line " << node->Row() << "."; + return false; + } + vfvc->setVectorField( vfPtr ); + vfvc->setUseNearest( _attrSet.getBool( _useNearestID ) ); + + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.h new file mode 100644 index 00000000..f533f2a2 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelCompVF.h @@ -0,0 +1,292 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelCompVF.h + * @brief Provides the definition of the vector field velocity component. + * The preferred velocity is defined for each agent based on where + * the agent is in relation a uniformly discretized 2D grid. + */ + +#ifndef __VEL_COMP_VF_H__ +#define __VEL_COMP_VF_H__ + +#include "CoreConfig.h" +#include "VelocityComponents/VelComponent.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelCompContext.h" +#include "VectorField.h" + +namespace Menge { + + // forward declaration + template < class R > + class ResourcePtr; + + /*! + * @brief forward declaration of VectorField resource pointer. + * see VectorField.h for more details + */ + typedef ResourcePtr< VectorField > VectorFieldPtr; + + namespace BFSM { + /*! + * @brief A velocity component that returns a preferred velocity whose direction + * and preferred speed are computed from a velocity field. + * + * If the velocity vector is of unit length, the preferred speed will be unchanged. + * Otherwise, the preferred speed is scaled by the length of the velocity vector. + */ + class MENGE_API VFVelComponent : public VelComponent { + public: + /*! + * @brief Default constructor. + */ + VFVelComponent(); + + /*! + * @brief Constructor. + * + * @param vf The VectorField to use for velocity computation. + * @param useNearest Determines if the velocity is computed by selecting the + * neareset vector (true) or the bilinear interpolation of + * four near-by cells (false). + */ + VFVelComponent( VectorFieldPtr & vf, bool useNearest ); + + /*! + * @brief Determines whether the vector field velocity component computes + * velocity from the nearest cell center or from a bilinear interpolation on + * the four near-by cells. + * + * @param useNearest Uses only nearest cell if true, 4-cell neighborhood if false. + */ + void setUseNearest( bool useNearest ) { _nearest = useNearest; } + + /*! + * @brief Sets the velocity field pointer. + * + * @param vf The managed pointer to the velocity field. + */ + void setVectorField( const VectorFieldPtr & vf ) { _vf = vf; } + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + friend class VecFieldVCContext; + + protected: + /*! + * @brief The vector field resource which provides preferred velocity vectors. + */ + VectorFieldPtr _vf; + + /*! + * @brief Determines if the vector selection is based on nearest (true) + * or bilinear interpolation (false) + */ + bool _nearest; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the VFVelComponent. + */ + class MENGE_API VecFieldVCContext : public VelCompContext { + public: + /*! + * @brief Constructor. + * + * @param vc A pointer to the underlying fsm velocity component. + * The context will *not* delete the velocity component. + */ + VecFieldVCContext( VFVelComponent * vc ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity component information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + * @param goal The agent's goal (although this may be ignored). + */ + virtual void draw3DGL( const Agents::BaseAgent * agt, const Goal * goal ); + + protected: + /*! + * @brief The underlying finite state machine velocity component. + */ + VFVelComponent * _vc; + + /*! + * @brief Displays only the local area around the agent + */ + bool _showLocal; + + /*! + * @brief Size of the local neighborhood to visualize + */ + int _neighborhood; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the VFVelComponent. + */ + class MENGE_API VFVCFactory : public VelCompFactory { + public: + /*! + * @brief Constructor. + */ + VFVCFactory(); + + /*! + * @brief The name of the velocity component. + * + * The velocity component's name must be unique among all registered + * velocity components. Each velocity component factory must override this function. + * + * @returns A string containing the unique velocity component name. + */ + virtual const char * name() const { return "vel_field"; } + + /*! + * @brief A description of the velocity component. + * + * Each velocity component factory must override this function. + * + * @returns A string containing the velocity component description. + */ + virtual const char * description() const { + return "Provides a preferred velocity which is derived from a velocity field defined"\ + " on a uniform, 2D discretization of the planning space."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity component. + * + * All VelCompFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity component type. The various field values + * of the instance will be set in a subsequent call to VelCompFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelComponent class. + */ + VelComponent * instance() const { return new VFVelComponent(); } + + /*! + * @brief Given a pointer to an VelComponent instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelComponent's type. + * (i.e. VelCompFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelCompFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vc A pointer to the velocity component whose attributes are to be set. + * @param node The XML node containing the velocity component attributes. + * @param behaveFldr The path to the behavior file. If the velocity component references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelComponent * vc, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + + /*! + * @brief The identifier for the "use_nearest" bool attribute. + */ + size_t _useNearestID; + }; + + } // namespace BFSM +} // namespace Menge + +#endif // __VEL_COMP_VF_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.cpp new file mode 100644 index 00000000..a0a2f03f --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelComponent.h" +#include "VelCompContext.h" +#include "VelComponentDatabase.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VelComponent + ///////////////////////////////////////////////////////////////////// + + VelCompContext * VelComponent::getContext() { + return new VelCompContext(); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of parsing function + ///////////////////////////////////////////////////////////////////// + + VelComponent * parseVelComponent( TiXmlElement * node, const std::string & behaveFldr ) { + return VelCompDB::getInstance( node, behaveFldr ); + } + + } // namespace BFSM +} // namespace Menge diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.h new file mode 100644 index 00000000..e99e7d5e --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponent.h @@ -0,0 +1,187 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelComponent.h + * @brief The definition of how preferred velocity is computed in a state. + */ +#ifndef __VEL_COMPONENT_H__ +#define __VEL_COMPONENT_H__ + +#include "fsmCommon.h" +#include "Element.h" +#include "PrefVelocity.h" +#include "MengeException.h" + +// STL +#include // stl vector + +namespace Menge { + + // forward declaration + template < class Element > + class ElementFactory; + + namespace BFSM { + + // FORWARD DECLARATIONS + class VelCompContext; + class Goal; + + /*! + * @brief Base exception class for preferred velocity computation. + */ + class MENGE_API VelCompException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + VelCompException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + VelCompException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the velocity component has an error which cannot be + * recovered from. + */ + class VelCompFatalException : public VelCompException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + VelCompFatalException() : MengeException(), VelCompException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + VelCompFatalException( const std::string & s ): MengeException(s), VelCompException(), MengeFatalException() {} + }; + + /*! + * @brief The base class for computing an agent's preferred velocity. + * + * Velocity components each have weights. The relative weights determine + * how multiple velocity components combine inside a single state. Their + * share is its own weight divided by the summed weight of all velocity + * components. + */ + class MENGE_API VelComponent : public Element { + public: + /*! + * @brief Default constructor. + */ + VelComponent() : Element() {} + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~VelComponent(){} + + public: + /*! + * @brief Called when the agent enters the state which possesses this velocity component. + * + * Gives the velocity component to intialize any agent-specific data. + * + * @param agent The agent who entered the state. + */ + virtual void onEnter( Agents::BaseAgent * agent ) {} + + /*! + * @brief Called when the agent leaves the state which possesses this velocity component. + * + * Gives the velocity component to restore any agent-specific data it might have changed. + * + * @param agent The agent who left the state. + */ + virtual void onExit( Agents::BaseAgent * agent ) {} + + /*! + * @brief Computes and sets the agent's preferred velocity. + * + * The velocity component directly sets preferred velocity values in the + * the provided preferred velocity instance. See Agents::PrefVelocity for details. + * Rather than setting the agent's preferred velocity value directly, a reference + * to a preferred velocity instance is passed in to make the use more general. + * This allows the computation of the preferred velocity for the agent, without + * necessarily making changes to it. + * + * @param agent The agent for which a preferred velocity is computed. + * @param goal The agent's goal (although this may be ignored). + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void setPrefVelocity( const Agents::BaseAgent * agent, const Goal * goal, Agents::PrefVelocity & pVel ) = 0; + + /*! + * @brief Provides a display context for interacting with this velocity component. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this vel component. + */ + virtual VelCompContext * getContext(); + + friend class ElementFactory< VelComponent >; + + }; + + /*! + * @brief Parses a TinyXML element containing a velocity component specification + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new velocity component implementation (NULL if no valid + * instance could be created). + */ + VelComponent * parseVelComponent( TiXmlElement * node, const std::string & behaveFldr ); + + + } // namespace BFSM +} // namespace Menge +#endif // __VEL_COMPONENT_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.cpp b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.cpp new file mode 100644 index 00000000..752a39cb --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.cpp @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelComponentDatabase.h" +#include "VelocityComponents/VelCompConst.h" +#include "VelocityComponents/VelCompGoal.h" +#include "VelocityComponents/VelCompVF.h" +#include "VelocityComponents/VelCompRoadMap.h" +#include "VelocityComponents/VelCompNavMesh.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::VelCompFactory, BFSM::VelComponent >::getElementName() { return "velocity component"; } + + template <> + void ElementDB< BFSM::VelCompFactory, BFSM::VelComponent >::addBuiltins() { + addFactory( new BFSM::ConstVCFactory() ); + addFactory( new BFSM::ConstDirVCFactory() ); + addFactory( new BFSM::ZeroVCFactory() ); + addFactory( new BFSM::GoalVCFactory() ); + addFactory( new BFSM::VFVCFactory() ); + addFactory( new BFSM::RoadMapVCFactory() ); + addFactory( new BFSM::NavMeshVCFactory() ); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.h new file mode 100644 index 00000000..72615bf7 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentDatabase.h @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelComponentDatabase.h + * @brief Central database for querying available behavior velocity components. + * + * For velocity components to be used in the finite state machine, they must register + * themselves into the VelCompDB. This is done via the PluginEngine. + */ + +#ifndef __VEL_COMPONENT_DATABASE_H__ +#define __VEL_COMPONENT_DATABASE_H__ + +#include "ElementDatabase.h" +#include "VelocityComponents/VelComponentFactory.h" +#include "VelocityComponents/VelComponent.h" + +namespace Menge { + namespace BFSM { + /*! + * @brief The database of registered velocity component implementations. + */ + typedef ElementDB< VelCompFactory, VelComponent > VelCompDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< BFSM::VelCompFactory, BFSM::VelComponent >::addBuiltins(); + template<> std::string ElementDB< BFSM::VelCompFactory, BFSM::VelComponent >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge + +#endif // __VEL_COMPONENT_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentFactory.h b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentFactory.h new file mode 100644 index 00000000..88b9bf9b --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityComponents/VelComponentFactory.h @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelComponentFactory.h + * @brief The factory for parsing xml data and instantiating + * velocity components. + */ + +#ifndef __VEL_COMPONENT_FACTORY_H__ +#define __VEL_COMPONENT_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "VelocityComponents/VelComponent.h" + +namespace Menge { + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a velocity component + * and instantiating particular instances. + */ + class MENGE_API VelCompFactory : public ElementFactory< VelComponent > { + }; + } // namespace BFSM +} // namespace Menge +#endif // __VEL_COMPONENT_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModContext.cpp b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModContext.cpp new file mode 100644 index 00000000..b7e416bb --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModContext.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelModifierContext.h" +#include "BaseAgent.h" +#include "VelModifier.h" +#include "shapes.h" +#include +#include "TextWriter.h" +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VelModContext + ///////////////////////////////////////////////////////////////////// + + std::string VelModContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "No context defined"; + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.cpp b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.cpp new file mode 100644 index 00000000..972e2014 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.cpp @@ -0,0 +1,77 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelModifier.h" +#include "VelModifierContext.h" +#include "VelModifierDatabase.h" +#include "BaseAgent.h" + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VelModifier + ///////////////////////////////////////////////////////////////////// + + VelModContext * VelModifier::getContext() { + return new VelModContext(); + } + + //////////////////////////////////////////////////////////// + + void VelModifier::onEnter(const Agents::BaseAgent * agent){ + registerAgent(agent); + }; + + //////////////////////////////////////////////////////////// + + void VelModifier::onLeave(const Agents::BaseAgent * agent){ + unregisterAgent(agent); + }; + + ///////////////////////////////////////////////////////////////////// + // Implementation of parsing function + ///////////////////////////////////////////////////////////////////// + + VelModifier * parseVelModifier( TiXmlElement * node, const std::string & behaveFldr ) { + return VelModDB::getInstance( node, behaveFldr ); + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.h b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.h new file mode 100644 index 00000000..4c4e02b1 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifier.h @@ -0,0 +1,212 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModifier.h + * @brief The definition of how preferred velocity is modified by a filter + */ +#ifndef __VEL_MODIFIER_H__ +#define __VEL_MODIFIER_H__ + +#include "fsmCommon.h" +#include "Element.h" +#include "PrefVelocity.h" +#include "MengeException.h" + +// STL +#include + +namespace Menge { + + // forward declaration + template < class Element > + class ElementFactory; + + namespace BFSM { + + // FORWARD DECLARATIONS + class VelModContext; + + /*! + * @brief Base exception class for preferred velocity modification. + */ + class MENGE_API VelModException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + VelModException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + VelModException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the velocity modifier has an error which cannot be + * recovered from. + */ + class VelModFatalException : public VelModException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + VelModFatalException() : MengeException(), VelModException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + VelModFatalException( const std::string & s ): MengeException(s), VelModException(), MengeFatalException() {} + }; + + /*! + * @brief The base class for modifying preferred velocities + * + * Each velocity modifier is allowed to change the input preferred velocity without limit based on arbitrary criteria. + * They have an order, which defines which order in which they are executed. Modifiers are chained so that the input + * of each modifier is the output of the previous, making order very important. + */ + class MENGE_API VelModifier : public Element { + public: + /*! + * @brief Default constructor. + */ + VelModifier() : Element() {} + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~VelModifier(){} + + public: + + /*! + * @brief Modifies the input preferred velocity in place. + * + * The main function of the velocity modifier. Applies its own algorithms + * to the input preferred velocity, transforming it into a new transform, in place. + * All VelModifier sub-classes must implement this function. + * + * @param agent The agent for which a preferred velocity is adapted. + * @param pVel The instance of Agents::PrefVelocity to set. + */ + virtual void adaptPrefVelocity( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ) = 0; + + /*! + * @brief Registers an agent for use with the VelModifier. + * + * When a velocity modifier is assigned to the agent, the agent is "registered" to it. + * If the velocity modifier needs to maintain per-agent data, this is the time to + * instantiate that data. Default implementation does nothing. + * + * @param agent The agent to be registered + */ + virtual void registerAgent(const Agents::BaseAgent * agent) {} + + /*! + * @brief Unregisters a registed agent. + * + * If an velocity modifier is removed from an agent, this allows the velocity + * modifier to destroy any agent-specific data. Default implementation does nothing. + * + * @param agent The agent to be unregistered + */ + virtual void unregisterAgent(const Agents::BaseAgent * agent) {} + + /*! + * @brief Called when an agent enters the state with this velocity modifier. + * + * This function calls registerAgent. Entering a state which has one or more + * velocity modifiers assigned to it, causes the velocity modifiers to be temporarily + * assigned to the agent. + * + * @param agent The agent entering the state + */ + void onEnter(const Agents::BaseAgent * agent); + + /*! + * @brief Called when an agent exits the state with this velocity modifier. + * + * The dual of onEnter. This function calls unregisterAgent. Agents departing a + * state with one or more velocity modifiers will be unregistered. + * + * @param agent The agent entering the state + */ + void onLeave(const Agents::BaseAgent * agent); + + /*! + * @brief Creates a copy of this velocity modifier. + * + * @returns A unique, deep copy of this velocity modifier. + */ + virtual VelModifier* copy() const = 0; + + /*! + * @brief Provides a display context for interacting with this velocity modifier. + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this velocity modifier + */ + virtual VelModContext * getContext(); + + friend class ElementFactory< VelModifier >; + }; + + /*! + * @brief Parses a TinyXML element containing a velocity modifier specification. + * + * @param node The TinyXML element + * @param behaveFldr The folder in which the behavior is defined -- all resources + * are defined relative to this folder. + * @returns A pointer to the new velocity modifier implementation (NULL if no valid + * instance could be created). + */ + VelModifier * parseVelModifier( TiXmlElement * node, const std::string & behaveFldr ); + + } // namespace BFSM +} // namespace Menge + +#endif // __VEL_MODIFIER_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierContext.h b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierContext.h new file mode 100644 index 00000000..ef067441 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierContext.h @@ -0,0 +1,122 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModifierContext.h + * @brief The definition of a basic UI context for finite + * state machine *velocity modifiers*. + */ + +#ifndef __VEL_MOD_CONTEXT_H__ +#define __VEL_MOD_CONTEXT_H__ + +#include "Context.h" +#include + +namespace Menge { + + namespace Agents { + class BaseAgent; + class PrefVelocity; + } + + namespace BFSM { + + // Forward declarations + class VelModifier; + + /*! + * @brief Base context for finite state machine velocity modifiers. + * + * This differs from the standard scene graph context by being + * dependent on an input agent. + */ + class MENGE_API VelModContext : public SceneGraph::Context { + public: + /*! + * @brief Constructor. + */ + VelModContext(){} + + /*! + * @brief This supplants the destructor. + * + * In order to preserve potential problems in windows when + * dlls do not share the same c-runtime library, the destructor + * is held to be private. To garbage collect an Velmodifier, + * the destroy method should be called (which in turn, will call + * the destructor from its own memory space, averting run-time + * crashes). + * + * Once this has been called, the VelModifier no longer exists. Calling + * methods or accessing members will produce indetermine behavior + * (most likely errors). + */ + void destroy() { delete this; } + + protected: + /*! + * @brief Destructor. + */ + virtual ~VelModContext(){} + + public: + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity modifier information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + */ + virtual void draw3DGL( const Agents::BaseAgent * agt){} + }; + + } // namespace BFSM +} // namespace Menge +#endif // __VEL_MOD_CONTEXT_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.cpp b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.cpp new file mode 100644 index 00000000..5d49f6b4 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.cpp @@ -0,0 +1,56 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelModifierDatabase.h" +#include "VelocityModifiers/VelModifierScale.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace Menge { + + // Specialization + template <> + std::string ElementDB< BFSM::VelModFactory, BFSM::VelModifier >::getElementName() { return "velocity modifier"; } + + template <> + void ElementDB< BFSM::VelModFactory, BFSM::VelModifier >::addBuiltins() { + addFactory(new BFSM::ScaleVMFactory()); + } +} // namespace Menge + +#endif // DOXYGEN_SHOULD_SKIP_THIS \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.h b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.h new file mode 100644 index 00000000..595ba2f6 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierDatabase.h @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModifierDatabase.h + * @brief Central database for querying available behavior velocity modifiers. + * + * For velocity modifiers to be used in the finite state machine, they must register + * themselves into the VelModDB. This is done via the PluginEngine. + */ + +#ifndef __VEL_MOD_DATABASE_H__ +#define __VEL_MOD_DATABASE_H__ + +#include "ElementDatabase.h" +#include "VelocityModifiers/VelModifierFactory.h" +#include "VelocityModifiers/VelModifier.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief The database of registered velocity component implementations. + */ + typedef ElementDB< VelModFactory, VelModifier > VelModDB; + + } // namespace BFSM + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + template<> void ElementDB< BFSM::VelModFactory, BFSM::VelModifier>::addBuiltins(); + template<> std::string ElementDB< BFSM::VelModFactory, BFSM::VelModifier >::getElementName(); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} // namespace Menge +#endif // __VEL___VEL_MOD_DATABASE_H__ diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierFactory.h b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierFactory.h new file mode 100644 index 00000000..1bd853e9 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierFactory.h @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModifierFactory.h + * @brief The factory for parsing xml data and instantiating + * velocity Modifierss. + */ + +#ifndef __VEL_MODIFIER_FACTORY_H__ +#define __VEL_MODIFIER_FACTORY_H__ + +#include "CoreConfig.h" +#include + +#include "ElementFactory.h" +#include "VelocityModifiers/VelModifier.h" + +namespace Menge { + + namespace BFSM { + /*! + * @brief A class for parsing the xml description of a velocity MODIFIER + * and instantiating particular instances. + */ + class MENGE_API VelModFactory : public ElementFactory< VelModifier > { + }; + } // namespace BFSM +} // namespace Menge + +#endif // __VEL_MODIFIER_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.cpp b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.cpp new file mode 100644 index 00000000..470e86ac --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.cpp @@ -0,0 +1,127 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelocityModifiers/VelModifierScale.h" +#include "BaseAgent.h" +#include +#include + +namespace Menge { + + namespace BFSM { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ScaleVelModifier + ///////////////////////////////////////////////////////////////////// + + ScaleVelModifier::ScaleVelModifier(): VelModifier(), _scale(1.f) { + } + + ///////////////////////////////////////////////////////////////////// + + ScaleVelModifier::ScaleVelModifier(const float scale): VelModifier(), _scale(scale) { + } + + ///////////////////////////////////////////////////////////////////// + + void ScaleVelModifier::setScale(const float scale) { + _scale = scale; + } + + ///////////////////////////////////////////////////////////////////// + + void ScaleVelModifier::adaptPrefVelocity(const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel) { + pVel.setSpeed(pVel.getSpeed() * _scale); + } + + ///////////////////////////////////////////////////////////////////// + + VelModContext * ScaleVelModifier::getContext() { + return new ScaleVMContext(this); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ScaleVMContext + ///////////////////////////////////////////////////////////////////// + + ScaleVMContext::ScaleVMContext(ScaleVelModifier *vm):VelModContext(), _vm(vm) { + }; + + ///////////////////////////////////////////////////////////////////// + + std::string ScaleVMContext::getUIText( const std::string & indent ) const { + std::stringstream ss; + ss << indent << "Scale Applied: " << _vm->getScale(); + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////// + + void ScaleVMContext::draw3DGL( const Agents::BaseAgent * agt) { + // draw preferred velocity + } + + ///////////////////////////////////////////////////////////////////// + + VelModifier * ScaleVelModifier::copy() const { + return new ScaleVelModifier(_scale); + }; + + ///////////////////////////////////////////////////////////////////// + // Implementation of ScaleVMFactory + ///////////////////////////////////////////////////////////////////// + + ScaleVMFactory::ScaleVMFactory() : VelModFactory() { + // TODO: This should support a numerical distribution + _scaleID = _attrSet.addFloatAttribute( "scale", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool ScaleVMFactory::setFromXML( VelModifier * vm, TiXmlElement * node, const std::string & behaveFldr ) const { + ScaleVelModifier * cvm = dynamic_cast< ScaleVelModifier * >( vm ); + assert( cvm != 0x0 && "Trying to set attributes of a Scale Velocity Modifier on an incompatible object" ); + + if ( ! VelModFactory::setFromXML( vm, node, behaveFldr ) ) return false; + + cvm->setScale( _attrSet.getFloat( _scaleID ) ); + return true; + } + + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.h b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.h new file mode 100644 index 00000000..c5ced12e --- /dev/null +++ b/src/Menge/MengeCore/BFSM/VelocityModifiers/VelModifierScale.h @@ -0,0 +1,239 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModifierScale.h + * @brief Provides the definition of a simple velocity modifier that simply + * scale's the preferred velocity's speed. + */ + +#ifndef __VEL_MOD_SCALE_H__ +#define __VEL_MOD_SCALE_H__ + +#include "CoreConfig.h" +#include "VelModifier.h" +#include "VelModifierContext.h" +#include "VelModifierFactory.h" + +namespace Menge { + + namespace BFSM { + + /*! + * @brief A velocity modifier that scales the input velocity's speed. + */ + class MENGE_API ScaleVelModifier : public VelModifier { + public: + /*! + * @brief Default constructor. + */ + ScaleVelModifier(); + + /*! + * @brief Constructor. + * + * @param scale The scale factor to apply to the preferred velocity's speed. + */ + ScaleVelModifier( const float scale ); + + /*! + * @brief Sets the scale factor. + * + * @param scale The the scale factor to apply to the preferred velocity's speed. + */ + void setScale( const float scale ); + + /*! + * @brief Scales the input preferred velocity's speed by the pre-defined scale + * factor. + * + * @param agent The agent for which a preferred velocity is modified. + * @param pVel The instance of Agents::PrefVelocity to set. + */ + void adaptPrefVelocity(const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ); + + /*! + * @brief Returns scale factor. + * + * @returns The scale factor stored in this modifier. + */ + float getScale() const { return _scale; } + + /*! + * @brief Creates a copy of this velocity modifier. + * + * @returns A unique, deep copy of this velocity modifier. + */ + VelModifier * copy() const; + + /*! + * @brief Provides a display context for interacting with this velocity modifier. + * + * @returns A pointer to a context for this vel modifier. + */ + virtual VelModContext * getContext(); //TODO: Implement the context + + friend class ScaleVMFactory; + + protected: + /*! + * @brief The scale factor to apply. + */ + float _scale; + + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The context for the ScaleVelModifier. + */ + //TODO: provide a context here + class MENGE_API ScaleVMContext : public VelModContext { + public: + /*! + * @brief Constructor. + * + * @param vm A pointer to the underlying fsm velocity modifier. + * The context will *not* delete the velocity modifier. + */ + ScaleVMContext( ScaleVelModifier * vm ); + + /*! + * @brief Provides a string to be printed in the display as a UI element + * detailing velocity modifier information. + * + * @param indent An optional string representing indentation to be + * applied to the text. It is prefixed at the start + * of each line. + * @returns The string for printing on the UI layer. + */ + virtual std::string getUIText( const std::string & indent="" ) const; + + /*! + * @brief Draw context elements into the 3D world. + * + * This should never be called in select mode. + * + * @param agt The particular agent for which the FSM is being visualized. + */ + virtual void draw3DGL( const Agents::BaseAgent * agt); + + protected: + /*! + * @brief The underlying finite state machine velocity modifier. + */ + ScaleVelModifier * _vm; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the ScaleVelModifier. + */ + class MENGE_API ScaleVMFactory : public VelModFactory { + public: + /*! + * @brief Constructor. + */ + ScaleVMFactory(); + + /*! + * @brief The name of the velocity modifier. + * + * The velocity modifiers's name must be unique among all registered + * velocity modifiers. Each velocity modifier factory must override this function. + * + * @returns A string containing the unique velocity modifier name. + */ + virtual const char * name() const { return "scale"; } + + /*! + * @brief A description of the velocity modifier. + * + * Each velocity modifier factory must override this function. + * + * @returns A string containing the velocity modifier description. + */ + virtual const char * description() const { + return "Scales the input preferred velocity by the given scale factor."; + }; + + protected: + /*! + * @brief Create an instance of this class's velocity modifier. + * + * All VelModFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding velocity modifier type. The various field values + * of the instance will be set in a subsequent call to VelModpFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated VelModifier class. + */ + VelModifier * instance() const { return new ScaleVelModifier(); } + + /*! + * @brief Given a pointer to an VelModifier instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this VelModifier's type. + * (i.e. VelModFactory::thisFactory has already been called and returned true.) + * If sub-classes of VelModFactory introduce *new* VelComponent parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param vm A pointer to the velocity modifier whose attributes are to be set. + * @param node The XML node containing the velocity modifier attributes. + * @param behaveFldr The path to the behavior file. If the velocity modifier references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( VelModifier * vm, TiXmlElement * node, const std::string & behaveFldr ) const; + + // TODO: This should support a numerical distribution + /*! + * @brief The identifier for the "scale" float attribute. + */ + size_t _scaleID; + }; + + } // namespace BFSM +} // namespace Menge +#endif // __VEL_MOD_SCALE_H \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/buildFSM.cpp b/src/Menge/MengeCore/BFSM/buildFSM.cpp new file mode 100644 index 00000000..327791ba --- /dev/null +++ b/src/Menge/MengeCore/BFSM/buildFSM.cpp @@ -0,0 +1,289 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file buildFSM.cpp + * @brief Functionality to realize Behavior FSM from configuration. + */ + +#include "FSMDescrip.h" +#include "FSM.h" +#include "NavMesh.h" +#include "fsmCommon.h" +#include "Core.h" +#include "State.h" +#include "Transitions/Transition.h" +#include "GoalSelectors/GoalSelector.h" +#include "GoalSelectors/GoalSelectorIdentity.h" +#include "GoalSelectors/GoalSelectorShared.h" +#include "SpatialQueries/SpatialQuery.h" +#include "Elevations/Elevation.h" +#include "VelocityComponents/VelCompConst.h" +#include "Events/Event.h" +#include "Events/EventException.h" +#include "Events/EventSystem.h" + +#include "BaseAgent.h" +#include "SimulatorInterface.h" +#include "SimulatorState.h" + +namespace Menge { + + namespace BFSM { + ///////////////////////////////////////////////////////////////////// + // Implementation of buildFSM + ///////////////////////////////////////////////////////////////////// + + FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ) { + // Acquire the spatial query instance + SPATIAL_QUERY = sim->getSpatialQuery(); + + //Global Simulator interface + SIMULATOR = sim; + + bool valid = true; + const size_t AGT_COUNT = sim->getNumAgents(); + FSM * fsm = new FSM( sim ); + + // Build the fsm + + //we'll need this iterator later + std::vector< VelModifier * >::iterator vItr; + + + // Map of state names to state IDs. + std::map< std::string, size_t > stateNameMap; + + // Copy the GoalSets + fsm->_goalSets.clear(); + fsm->_goalSets.insert( fsmDescrip._goalSets.begin(), fsmDescrip._goalSets.end() ); + fsmDescrip._goalSets.clear(); + + // 1. Create states + // a. Add velocity components and actions + // b. add to fsm + + std::list< StateDescrip * >::const_iterator sItr = fsmDescrip._states.begin(); + for ( ; sItr != fsmDescrip._states.end(); ++sItr ) { + StateDescrip * sData = *sItr; + State * s = fsmDescrip.addState( sData ); + + if ( s == 0x0 ) { + logger << Logger::ERR_MSG << "Error creating state!"; + delete fsm; + return 0x0; + } + if ( VERBOSE ) logger << Logger::INFO_MSG << "\tAdding state: " << s->getName() << "(" << s->getID() << ")\n"; + + + // State's goal selector + GoalSelector * gs = sData->_goalSelector; + if ( gs == 0x0 ) { + logger << Logger::WARN_MSG << "The state " << sData->_name << " doesn't specify a goal selector. The identity goal selector will be used."; + gs = new IdentityGoalSelector(); + } + + try { + gs->setGoalSet( fsm->getGoalSets() ); // possibly throws GoalSelectorException + s->setGoalSelector( gs ); // possibly throws GoalSelectorException + } catch ( GoalSelectorException ) { + logger << Logger::ERR_MSG << "Problem initializing the goal selector for the state " << s->getName() << "."; + delete fsm; + return 0x0; + } + sData->_goalSelector = 0x0; + + // construct each velocity component + if ( sData->_velComponent == 0x0 ) { + logger << Logger::WARN_MSG << "The state " << sData->_name << " doesn't specify a velocity component. The zero velocity component will be used."; + s->setVelComponent( new ZeroVelComponent() ); + } else { + s->setVelComponent( sData->_velComponent ); + sData->_velComponent = 0x0; + } + + // transfer each action + std::list< Action * >::iterator aItr = sData->_actions.begin(); + for ( ; aItr != sData->_actions.end(); ++aItr ) { + s->addAction( *aItr ); + } + sData->_actions.clear(); + + //transfer velocity modifiers from the state description + vItr = sData->_velModifiers.begin(); + for ( ; vItr != sData->_velModifiers.end(); ++vItr ) { + s->addVelModifier( *vItr ); + } + sData->_velModifiers.clear(); + + + // Set start node + size_t stateID = fsm->addNode( s ); + stateNameMap[ sData->_name ] = stateID; + } + + // Connect all shared goal selectors + std::map< std::string, size_t >::iterator stateItr = stateNameMap.begin(); + for ( ; stateItr != stateNameMap.end(); ++stateItr ) { + std::string stateName = stateItr->first; + size_t stateID = stateItr->second; + State * state = fsm->getNode( stateID ); + SharedGoalSelector * gs = dynamic_cast< SharedGoalSelector * >( state->getGoalSelector() ); + if ( gs != 0x0 ) { + if ( stateNameMap.count( gs->_stateName ) == 0 ) { + logger << Logger::ERR_MSG << "Found shared goal selector defined on line " << gs->_lineNo << ", but unable to locate state with the provided name: \"" << gs->_stateName << "\"."; + delete fsm; + return 0x0; + } + State * src = fsm->getNode( stateNameMap[ gs->_stateName ] ); + if ( dynamic_cast< SharedGoalSelector * >( src->getGoalSelector() ) ) { + logger << Logger::ERR_MSG << "Shared goal selector defined on line " << gs->_lineNo << " references a state with a shared goal. The source state must have a full goal selector definition."; + delete fsm; + return 0x0; + } + state->clearGoalSelector(); + GoalSelector * srcGS = src->getGoalSelector(); + srcGS->setPersistence( true ); + state->setGoalSelector( srcGS ); + } + } + + if ( VERBOSE ) logger << Logger::INFO_MSG << "There are " << fsmDescrip._transitions.size() << " transitions\n"; + + // 2. Create transitions + std::map< std::string, std::list< Transition * > >::iterator stItr = fsmDescrip._transitions.begin(); + for ( ; stItr != fsmDescrip._transitions.end(); ++stItr ) { + const std::string fromName = stItr->first; + std::list< Transition * > & tList = stItr->second; + + // Determine if the origin state is valid + if ( fsmDescrip._stateNameMap.find( fromName ) == fsmDescrip._stateNameMap.end() ) { + logger << Logger::ERR_MSG << "Transition with invalid from node name: " << fromName << "."; + delete fsm; + return 0x0; + } + + // Try to connect the transitions to the destination(s) + std::list< Transition * >::iterator tItr = tList.begin(); + for ( ; tItr != tList.end(); ++tItr ) { + Transition * t = *tItr; + if ( ! t->connectStates( fsmDescrip._stateNameMap ) ) { + delete fsm; + return 0x0; + } + fsm->addTransition( stateNameMap[ fromName ], t ); + } + tList.clear(); + } + fsmDescrip._transitions.clear(); + + ////////////// + + // copy over the velocity modifiers + vItr = fsmDescrip._velModifiers.begin(); + for ( ; vItr != fsmDescrip._velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer + fsm->addVelModifier( *vItr ); + + } + fsmDescrip._velModifiers.clear(); + + // 3. Query simulator and fsm for possible reasons to have a task + fsm->collectTasks(); + for ( std::list< Task * >::iterator itr = fsmDescrip._tasks.begin(); + itr != fsmDescrip._tasks.end(); + ++itr ) { + fsm->addTask( (*itr) ); + } + fsmDescrip._tasks.clear(); + + // spatial query and elevation tasks + fsm->addTask( SPATIAL_QUERY->getTask() ); + if ( sim->getElevationInstance() ) { + // NOTE: The elevation instance is null because none were specified. + // Eventually, the default elevation will be set. + // HOWEVER, if the default ever changes such that it requires a task, + // this won't catch it!!! So, make sure the default never requires + // a task. + fsm->addTask( sim->getElevationInstance()->getTask() ); + } + + logger << Logger::INFO_MSG << "There are " << fsm->getTaskCount() << " registered tasks.\n"; + fsm->doTasks(); + + + + // 5. Initialize all agents + if ( VERBOSE ) logger << Logger::INFO_MSG << "Initializing agents:\n"; + Agents::SimulatorState * initState = sim->getInitialState(); + + for ( size_t a = 0; a < AGT_COUNT; ++a ) { + Agents::BaseAgent * agt = sim->getAgent( a ); + // update current state to class-appropriate value + const std::string stateName = initState->getAgentState( agt->_id ); + + std::map< std::string, size_t >::iterator stateIDItr = stateNameMap.find( stateName ); + if ( stateIDItr == stateNameMap.end() ) { + logger << Logger::ERR_MSG << "Agent " << agt->_id << " requested to start in an unknown state: " << stateName << "."; + delete fsm; + return 0x0; + } + size_t stateID = stateIDItr->second; + + // initialize velocity to preferred velocity + State * cState = fsm->getNode( stateID ); + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "Agent " << agt->_id << " starts in " << cState->getName() << "."; + } + fsm->setCurrentState( agt, stateID ); + cState->enter( agt ); + // TODO: Restore support for defining inital velocity state: zero or preferred + agt->_vel.set( Vector2( 0.f, 0.f ) ); + + //register the agent for all vel modifiers + vItr = fsm->_velModifiers.begin(); + for ( ; vItr != fsm->_velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer + ( *vItr )->registerAgent(agt); + } + } + + ACTIVE_FSM = fsm; + + return fsm; + } + } // namespace BFSM +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/fsmCommon.cpp b/src/Menge/MengeCore/BFSM/fsmCommon.cpp new file mode 100644 index 00000000..e10e7a0a --- /dev/null +++ b/src/Menge/MengeCore/BFSM/fsmCommon.cpp @@ -0,0 +1,49 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "fsmCommon.h" + +#if 1 +// Common utilities for the fsm module +namespace Menge { + namespace BFSM { + + float SIM_TIME_STEP = 0.0f; + } // namespace BFSM +} // namespace Menge +#endif \ No newline at end of file diff --git a/src/Menge/MengeCore/BFSM/fsmCommon.h b/src/Menge/MengeCore/BFSM/fsmCommon.h new file mode 100644 index 00000000..56f7b012 --- /dev/null +++ b/src/Menge/MengeCore/BFSM/fsmCommon.h @@ -0,0 +1,56 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file fsmCommon.h + * @brief Collection of convenient pre-compiler information for fsm definitions. + */ + +#ifndef __FSM_COMMON_H__ +#define __FSM_COMMON_H__ + +#include "mengeCommon.h" + +namespace Menge { + // Forward declartion + namespace Agents { + class BaseAgent; + class Obstacle; + } +} // namespace Menge +#endif // __FSM_COMMON_H__ diff --git a/src/Menge/MengeCore/Core.cpp b/src/Menge/MengeCore/Core.cpp new file mode 100644 index 00000000..655c769c --- /dev/null +++ b/src/Menge/MengeCore/Core.cpp @@ -0,0 +1,58 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Core.h" +#include "SpatialQueries/SpatialQuery.h" +#include "FSM.h" +#include "Events/EventSystem.h" + +namespace Menge { + BFSM::FSM * ACTIVE_FSM = 0x0; + + float SIM_TIME = 0.f; + + float SIM_TIME_STEP = 0.f; + + Agents::SpatialQuery * SPATIAL_QUERY = 0x0; + + Agents::Elevation * ELEVATION = 0x0; + + Agents::SimulatorInterface * SIMULATOR = 0x0; + + Menge::EventSystem * EVENT_SYSTEM = new Menge::EventSystem(); +} diff --git a/src/Menge/MengeCore/Core.h b/src/Menge/MengeCore/Core.h new file mode 100644 index 00000000..bc7107ac --- /dev/null +++ b/src/Menge/MengeCore/Core.h @@ -0,0 +1,105 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Core.h + * @brief A set of global variables for use by the entire + * finite state machine. + */ + +#ifndef __CORE_H__ +#define __CORE_H__ + +#include "CoreConfig.h" + +/*! + * @namespace Menge + * @brief The core namespace. All elements of Menge are contained in this namespace. + */ +namespace Menge { + + // forward declarations + namespace Agents { + class SpatialQuery; + class SimulatorInterface; + class Elevation; + } + + namespace BFSM { + class FSM; + } + class EventSystem; + + /*! + * @brief The fsm running for the simulation. + */ + extern MENGE_API BFSM::FSM * ACTIVE_FSM; + + /*! + * @brief The global simulation time. + */ + extern MENGE_API float SIM_TIME; + + /*! + * @brief The simulation time step. + */ + extern MENGE_API float SIM_TIME_STEP; + + /*! + * @brief The spatial query structure for the simulation. + */ + extern MENGE_API Agents::SpatialQuery * SPATIAL_QUERY; + + /*! + * @brief The elevation structure for the simulation. + */ + extern MENGE_API Agents::Elevation * ELEVATION; + + /*! + * @brief The simulator for use with some plugins that need it + */ + extern MENGE_API Agents::SimulatorInterface * SIMULATOR; + + /*! + * @brief The event system. + */ + extern MENGE_API EventSystem * EVENT_SYSTEM; + +} // namespace Menge + +#endif //__CORE_H__ diff --git a/src/Menge/MengeCore/CoreConfig.h b/src/Menge/MengeCore/CoreConfig.h new file mode 100644 index 00000000..18d39ecb --- /dev/null +++ b/src/Menge/MengeCore/CoreConfig.h @@ -0,0 +1,111 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file CoreConfig.h + * @brief Sets up the proper compiler directives for + * platform and dll export/import + */ + +#ifndef __CORE_CONFIG_H__ +#define __CORE_CONFIG_H__ + +#if defined(_MSC_VER) + // Exposing templated instances in a dll requires special handling + // There is no problem as long as all code is built on the same machine. + // Until this is finally corrected, we will simply suppress the warning. + // + // TODO: Correct the problem and remove the warning suppression. + #pragma warning(disable:4251) +#endif + +//// First determine compiling environment +#if defined( WIN32 ) || defined( _WIN32 ) + /*! + * @brief defines the build environment as windows + */ + #define PLUGIN_WIN32 1 +#else + /*! + * @brief defines the build environment as linux + */ + #define PLUGIN_LINUX 1 +#endif + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + #if defined( MENGE_STATICLIB ) + #define MENGE_API + #define MATHEXTERN + #else + #if defined( MENGECORE_EXPORTS ) + // We are building the DLL, export the symbols tagged like this + #define MENGE_API __declspec(dllexport) + #define MATHEXTERN + #else + // If we are consuming the DLL, import the symbols tagged like this + #define MENGE_API __declspec(dllimport) + #define MATHEXTERN extern + #endif + #endif + +#elif defined(__GNUC__) + + #define MATHEXTERN + #if defined( MENGE_STATICLIB ) + #define MENGE_API + #else + #if defined( MENGECORE_EXPORTS ) + #define MENGE_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define MENGE_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __CORE_CONFIG_H__ diff --git a/src/Menge/MengeCore/Math/Geometry2D.cpp b/src/Menge/MengeCore/Math/Geometry2D.cpp new file mode 100644 index 00000000..a51f4f7c --- /dev/null +++ b/src/Menge/MengeCore/Math/Geometry2D.cpp @@ -0,0 +1,240 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Geometry2D.h" +#include + +namespace Menge { + + namespace Math { + + ///////////////////////////////////////////////////////////////////// + // Implementation of CircleShape + ///////////////////////////////////////////////////////////////////// + + CircleShape::CircleShape( const CircleShape & shape ) { + _center = shape._center; + _radSqd = shape._radSqd; + } + + ///////////////////////////////////////////////////////////////////// + + CircleShape::CircleShape( const CircleShape & shape, const Vector2 & offset ) { + _center = shape._center + offset; + _radSqd = shape._radSqd; + } + + ///////////////////////////////////////////////////////////////////// + + CircleShape CircleShape::operator+( const Vector2 & pt ) { + CircleShape circle( *this ); + circle._center += pt; + return circle; + } + + ///////////////////////////////////////////////////////////////////// + + bool CircleShape::containsPoint( const Vector2 & pt ) const { + float distSq = absSq( pt - _center ); + return distSq < _radSqd; + } + + ///////////////////////////////////////////////////////////////////// + + bool CircleShape::containsPoint( const Vector2 & pt, const Vector2 & pos ) const { + float distSq = absSq( pt - pos ); + return distSq < _radSqd; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of AABBShape + ///////////////////////////////////////////////////////////////////// + + AABBShape::AABBShape():Geometry2D(), _minPt(0.f,0.f), _maxPt(0.f,0.f), _halfSize(0.f,0.f) { + } + + ///////////////////////////////////////////////////////////////////// + + AABBShape::AABBShape( const Vector2 & minPt, const Vector2 & maxPt ):Geometry2D(), _minPt(minPt), _maxPt(maxPt) { + assert( _minPt.x() <= _maxPt.x() && _minPt.y() <= _maxPt.y() && "Improper definition of AABB" ); + _halfSize = (maxPt-minPt) * 0.5f; + } + + ///////////////////////////////////////////////////////////////////// + + AABBShape::AABBShape( const AABBShape & shape ) { + _minPt = shape._minPt; + _maxPt = shape._maxPt; + _halfSize = shape._halfSize; + } + + ///////////////////////////////////////////////////////////////////// + + AABBShape::AABBShape( const AABBShape & shape, const Vector2 & offset ) { + _minPt = shape._minPt + offset; + _maxPt = shape._maxPt + offset; + _halfSize = shape._halfSize; + } + + ///////////////////////////////////////////////////////////////////// + + AABBShape AABBShape::operator+( const Vector2 & pt ) { + AABBShape aabb( *this ); + aabb._minPt += pt; + aabb._maxPt += pt; + return aabb; + } + + ///////////////////////////////////////////////////////////////////// + + bool AABBShape::containsPoint( const Vector2 & pt ) const { + const float x = pt.x(); + const float y = pt.y(); + return ( x >= _minPt.x() && x <= _maxPt.x() && + y >= _minPt.y() && y <= _maxPt.y() ); + } + + ///////////////////////////////////////////////////////////////////// + + bool AABBShape::containsPoint( const Vector2 & pt, const Vector2 & pos ) const { + const float x = pt.x(); + const float y = pt.y(); + Vector2 minPt = pos - _halfSize; + Vector2 maxPt = pos + _halfSize; + return ( x >= minPt.x() && x <= maxPt.x() && + y >= minPt.y() && y <= maxPt.y() ); + } + + ///////////////////////////////////////////////////////////////////// + + void AABBShape::set( const Vector2 & minPt, const Vector2 & maxPt ) { + _minPt.set( minPt ); + _maxPt.set( maxPt ); + _halfSize = ( _maxPt - _minPt ) * 0.5f; + } + + ///////////////////////////////////////////////////////////////////// + + void AABBShape::setSize( const Vector2 & size ) { + _maxPt = _minPt + size; + _halfSize = size * 0.5f; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of OBBShape + ///////////////////////////////////////////////////////////////////// + + OBBShape::OBBShape():Geometry2D(), _pivot(0.f,0.f), _size(0.f,0.f), _cosTheta(1.f), _sinTheta(0.f) { + } + + ///////////////////////////////////////////////////////////////////// + + OBBShape::OBBShape( const Vector2 & pivot, const Vector2 & size, float angle ):Geometry2D(), _pivot(pivot), _size(size), _cosTheta(cos(angle)), _sinTheta(sin(angle)) { + } + + ///////////////////////////////////////////////////////////////////// + + OBBShape::OBBShape( const OBBShape & shape ) { + _pivot = shape._pivot; + _size = shape._size; + _halfSize = shape._halfSize; + _cosTheta = shape._cosTheta; + _sinTheta = shape._sinTheta; + } + + ///////////////////////////////////////////////////////////////////// + + OBBShape::OBBShape( const OBBShape & shape, const Vector2 & offset ) { + _pivot = shape._pivot + offset; + _size = shape._size; + _halfSize = shape._halfSize; + _cosTheta = shape._cosTheta; + _sinTheta = shape._sinTheta; + } + + ///////////////////////////////////////////////////////////////////// + + OBBShape OBBShape::operator+( const Vector2 & pt ) { + OBBShape obb( *this ); + obb._pivot += pt; + return obb; + } + + ///////////////////////////////////////////////////////////////////// + + bool OBBShape::containsPoint( const Vector2 & pt ) const { + // Offset position to the space of the oriented bounding box. + Vector2 disp = pt - _pivot; + // rotate NEGATIVELY + const float x = disp.x() * _cosTheta + disp.y() * _sinTheta; + const float y = disp.y() * _cosTheta - disp.x() * _sinTheta; + return ( x >= 0.f && x <= _size.x() && + y >= 0.f && y <= _size.y() ); + } + + ///////////////////////////////////////////////////////////////////// + + bool OBBShape::containsPoint( const Vector2 & pt, const Vector2 & pos ) const { + // point relative to the center + // Scaled by 2 so I can use the size value directly to do the test + Vector2 p = ( pt - pos ) * 2.f; + // rotate it + const float x = p.x() * _cosTheta + p.y() * _sinTheta; + const float y = p.y() * _cosTheta - p.x() * _sinTheta; + + return ( x >= -_size.x() && x <= _size.x() && + y >= -_size.y() && y <= _size.y() ); + } + + ///////////////////////////////////////////////////////////////////// + + void OBBShape::set( const Vector2 & pivot, float width, float height, float angle ) { + _pivot.set( pivot ); + _size.set( width, height ); + _cosTheta = cos( angle ); + _sinTheta = sin( angle ); + } + + ///////////////////////////////////////////////////////////////////// + + void OBBShape::setAngle( float angle ) { + _cosTheta = cos( angle ); + _sinTheta = sin( angle ); + } + } // namespace Math +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/Geometry2D.h b/src/Menge/MengeCore/Math/Geometry2D.h new file mode 100644 index 00000000..0cf8afd4 --- /dev/null +++ b/src/Menge/MengeCore/Math/Geometry2D.h @@ -0,0 +1,412 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Geometry2D.h + * @brief Definition of various shapes for defining spatial relationships. + */ + +#ifndef __GEOMETRY_2D_H__ +#define __GEOMETRY_2D_H__ + +#include "mengeCommon.h" + +namespace Menge { + + namespace Math { + + /*! + * @brief Abstract 2d Geometry class for FSM queries. + * + * Supports queries to determine if points lie inside/outside a particular + * shape. + */ + class MENGE_API Geometry2D { + public: + /*! + * @brief Constructor + */ + Geometry2D(){} + + /*! + * @brief Simple destructor + */ + virtual ~Geometry2D(){} + + /*! + * @brief Determine if the point is inside the shape based on + * the instance properties. + * + * @param pt The point to test. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt ) const = 0; + + /*! + * @brief Determine if the point is inside the shape, not located at the + * instance value, but at the given position. Definition of "at the + * given position" is defined by each shape. + * + * @param pt The point to test. + * @param pos The "position" of the shape. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt, const Vector2 & pos ) const = 0; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Circle shape + */ + class MENGE_API CircleShape : public Geometry2D { + public: + /*! + * @brief Default constructor + */ + CircleShape(): _center(0.f,0.f), _radSqd(1.f) {} + + /*! + * @brief Constructor + * + * @param center The position of the circle's center. + * @param radius The radius of the circle. + */ + CircleShape( const Vector2 & center, float radius ):Geometry2D(), _center(center), _radSqd(radius*radius) {} + + /*! + * @brief Copy constructor + * + * @param shape The shape to copy from. + */ + CircleShape( const CircleShape & shape ); + + /*! + * @brief Initializes this shape as an translated version of the input shape. + * + * @param shape The shape to copy from. + * @param offset defines an offset from the copied CircleShape for the new CircleShape center + */ + CircleShape( const CircleShape & shape, const Vector2 & offset ); + + /*! + * @brief Construct an offset version of this shape. + * + * @param pt The offset value. + * @returns A new CircleShape offset from this one by the vector pt. + */ + CircleShape operator+( const Vector2 & pt ); + + /*! + * @brief Sets the radius of the circle. + * + * @param radius The circle's radius. + */ + void setRadius( float radius ) { _radSqd = radius * radius; } + + /*! + * @brief Sets the center of the circle. + * + * @param center The circle's center. + */ + void setCenter( const Vector2 & center ) { _center.set( center ); } + + /*! + * @brief Sets the properties of the circle. + * + * @param center The circle's center. + * @param radius The circle's radius. + */ + void set( const Vector2 & center, float radius ) { _center.set( center ); _radSqd = radius * radius; } + + /*! + * @brief Determine if the point is inside the shape based on + * the instance properties. + * + * @param pt The point to test. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt ) const; + + /*! + * @brief Determine if the point is inside a circle, centered on the + * given position. + * + * @param pt The point to test. + * @param pos The position of the circle's center. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt, const Vector2 & pos ) const; + + protected: + /*! + * @brief Center of the circle + */ + Vector2 _center; + + /*! + * @brief Squared radius of the circle + */ + float _radSqd; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Axis-aligned bounding box + */ + class MENGE_API AABBShape : public Geometry2D { + public: + /*! + * @brief Default constructor + */ + AABBShape(); + + /*! + * @brief Constructor + * + * @param minPt The minimum values of the bounding box along + * the x- and y-axes, respectively. + * @param maxPt The maximum values of the bounding box along + * the x- and y-axes, respectively. + */ + AABBShape( const Vector2 & minPt, const Vector2 & maxPt ); + + /*! + * @brief Copy constructor + * + * @param shape The shape to copy from. + */ + AABBShape( const AABBShape & shape ); + + /*! + * @brief Initializes this shape as an translated version of the input shape. + * + * @param shape The shape to copy from. + * @param offset defines an offset from the copied AABBShape for the new AABBShape + */ + AABBShape( const AABBShape & shape, const Vector2 & offset ); + + /*! + * @brief Construct an offset version of this shape. + * + * @param pt The offset value. + * @returns A new AABBShape offset from this one by the vector pt. + */ + AABBShape operator+( const Vector2 & pt ); + + /*! + * @brief Determine if the point is inside the shape based on + * the instance properties. + * + * @param pt The point to test. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt ) const; + + /*! + * @brief Determine if the point is inside a AABB, centered on the + * given position. + * + * @param pt The point to test. + * @param pos The position of the circle. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt, const Vector2 & pos ) const; + + /*! + * @brief Sets the extent of the AABB. + * + * @param minPt The minimum point (along the x- and y-axes). + * @param maxPt The maximum point (along the x- and y-axes). + */ + void set( const Vector2 & minPt, const Vector2 & maxPt ); + + /*! + * @brief Sets the size of the AABB. + * + * It implicitly changes the maximum extent of the box, keeping the + * minimum point where it is. + * + * @param size The width and height of the box. + */ + void setSize( const Vector2 & size ); + + protected: + /*! + * @brief The minimum extent of the bounding box + */ + Vector2 _minPt; + + /*! + * @brief The maximum extent of the bounding box + */ + Vector2 _maxPt; + + /*! + * @brief The size of the bounding box (along the x- and y- axes). + */ + Vector2 _halfSize; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Oriented bounding box + */ + class MENGE_API OBBShape : public Geometry2D { + public: + /*! + * @brief Default constructor + */ + OBBShape(); + + /*! + * @brief Constructor + * + * @param pivot The minimum values of the unrotated bounding box along + * the x- and y-axes, respectively. The bounding box + * gets rotated around this point. + * @param size The size of the bounding box along the LOCAL x- and + * y-axes, respectively. + * @param angle The angle of rotation (in radians). + */ + OBBShape( const Vector2 & pivot, const Vector2 & size, float angle ); + + /*! + * @brief Copy constructor + * + * @param shape The shape to copy from. + */ + OBBShape( const OBBShape & shape ); + + /*! + * @brief Initializes this shape as an translated version of the input shape. + * + * @param shape The shape to copy from. + * @param offset offset vector from the copied shape + */ + OBBShape( const OBBShape & shape, const Vector2 & offset ); + + /*! + * @brief Construct an offset version of this shape. + * + * @param pt The offset value. + * @returns A new OBBShape offset from this one by the vector pt. + */ + OBBShape operator+( const Vector2 & pt ); + + /*! + * @brief Determine if the point is inside the shape based on + * the instance properties. + * + * @param pt The point to test. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt ) const; + + /*! + * @brief Determine if the point is inside a OBB, centered on the + * given position. + * + * @param pt The point to test. + * @param pos The position of the circle. + * @returns True if the point is inside the shape, false otherwise. + */ + virtual bool containsPoint( const Vector2 & pt, const Vector2 & pos ) const; + + /*! + * @brief Sets the extent of the OBB. + * + * @param pivot The pivot point of the OBB + * @param width The width of the unrotated box (length along the x-axis). + * @param height The width of the unrotated box (length along the x-axis). + * @param angle The angle of rotation (in radians) around the pivot point. + */ + void set( const Vector2 & pivot, float width, float height, float angle ); + + /*! + * @brief Sets the size of the OBB. + * + * The pivot point and angle remain unchanged. + * + * @param size The width and height of the box. + */ + void setSize( const Vector2 & size ) { _size.set( size ); } + + /*! + * @brief Sets the angle of the OBB. + * + * The pivot point and size remain unchanged. + * + * @param angle The angle (in radians) the OBB is rotated around its pivot. + */ + void setAngle( float angle ); + + protected: + /*! + * @brief The minimum corners of the bounding box (the box is rotated around this point). + */ + Vector2 _pivot; + + /*! + * @brief The width and height of the box (along its local coordinate system). + */ + Vector2 _size; + + /*! + * @brief The half width and height of the box. + */ + Vector2 _halfSize; + + /*! + * @brief The cosine of the box's angle of rotation + * (used for accelerating queries). + */ + float _cosTheta; + + /*! + * @brief The sine of the box's angle of rotation + * (used for accelerating queries). + */ + float _sinTheta; + }; + } // namespace Math +} // namespace Menge + +#endif // __GEOMETRY_2D_H__ diff --git a/src/Menge/MengeCore/Math/Line.cpp b/src/Menge/MengeCore/Math/Line.cpp new file mode 100644 index 00000000..8a2ec2fd --- /dev/null +++ b/src/Menge/MengeCore/Math/Line.cpp @@ -0,0 +1,65 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Line.h" + +namespace Menge { + + namespace Math { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of Line + //////////////////////////////////////////////////////////////////////////// + + Line::Line(): _point(), _direction() { + } + + //////////////////////////////////////////////////////////////////////////// + + Line::Line( const Vector2 & p, const Vector2 & d ):_point(p), _direction(d) { + } + + //////////////////////////////////////////////////////////////////////////// + + Vector2 Line::nearestPt( const Vector2 & p ) const { + float t = _direction * ( p - _point ); + return _point + t * _direction; + } + + } // namespace Math +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/Line.h b/src/Menge/MengeCore/Math/Line.h new file mode 100644 index 00000000..41f7595e --- /dev/null +++ b/src/Menge/MengeCore/Math/Line.h @@ -0,0 +1,95 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __LINE_H__ +#define __LINE_H__ + +/*! + * @file Line.h + * @brief Contains the definition for an line used as a linear constraint + * (e.g. ORCA half plane) + */ + +#include "mengeCommon.h" + +namespace Menge { + + namespace Math { + + /*! + * @brief Defines a directed line. + */ + class MENGE_API Line { + public: + /*! + * @brief Default constructor. + */ + Line(); + + /*! + * @brief Explicit constructor. + * + * @param p A point on the line. + * @param d A unit-length vector defining the direction of the line. + * the line is defined by p + dt, where t in the range + * [-infinity, infinity]. + */ + Line( const Vector2 & p, const Vector2 & d ); + + /*! + * @brief Returns the nearest point on the line to p + * + * @param p The point to which we want to find + * the nearest point. + * @returns A point on the line that is closest to p. + */ + Vector2 nearestPt( const Vector2 & p ) const; + + /*! + * @brief A point on the directed line. + */ + Vector2 _point; + + /*! + * @brief The direction of the directed line. + */ + Vector2 _direction; + }; + } // namespace Math +} // namespace Menge +#endif // __LINE_H__ diff --git a/src/Menge/MengeCore/Math/Matrix.cpp b/src/Menge/MengeCore/Math/Matrix.cpp new file mode 100644 index 00000000..4ed565ff --- /dev/null +++ b/src/Menge/MengeCore/Math/Matrix.cpp @@ -0,0 +1,279 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Matrix.h" +#include +#include + +namespace Menge { + + namespace Math { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Matrix4x4 + /////////////////////////////////////////////////////////////////////////// + + Matrix4x4 IDENTITY4x4; + + /////////////////////////////////////////////////////////////////////////// + + Matrix4x4::Matrix4x4() { + identity(); + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::identity() { + memset(_flatData, 0, sizeof(float)*16); + _matData[0][0] = _matData[1][1] = _matData[2][2] = _matData[3][3] = 1.f; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::setRow( int row, float v0, float v1, float v2, float v3 ) { + assert( row >= 0 && row < 4 && "Invalid row index!\n" ); + _matData[row][0] = v0; + _matData[row][1] = v1; + _matData[row][2] = v2; + _matData[row][3] = v3; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::setRow( int row, const Vector3 & vec, float v3 ) { + assert( row >= 0 && row < 4 && "Invalid row index!\n" ); + _matData[row][0] = vec._x; + _matData[row][1] = vec._y; + _matData[row][2] = vec._z; + _matData[row][3] = v3; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::scale( const Vector3 & scale, Matrix4x4 & m ) { + _matData[0][0] = m._matData[0][0] * scale._x; + _matData[0][1] = m._matData[0][1] * scale._x; + _matData[0][2] = m._matData[0][2] * scale._x; + _matData[0][3] = m._matData[0][3] * scale._x; + + _matData[1][0] = m._matData[1][0] * scale._y; + _matData[1][1] = m._matData[1][1] * scale._y; + _matData[1][2] = m._matData[1][2] * scale._y; + _matData[1][3] = m._matData[1][3] * scale._y; + + _matData[2][0] = m._matData[2][0] * scale._z; + _matData[2][1] = m._matData[2][1] * scale._z; + _matData[2][2] = m._matData[2][2] * scale._z; + _matData[2][3] = m._matData[2][3] * scale._z; + + _matData[3][0] = m._matData[3][0]; + _matData[3][1] = m._matData[3][1]; + _matData[3][2] = m._matData[3][2]; + _matData[3][3] = m._matData[3][3]; + + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::scaleRight( const Vector3 & scale, Matrix4x4 & m ) { + _matData[0][0] = m._matData[0][0] * scale._x; + _matData[1][0] = m._matData[1][0] * scale._x; + _matData[2][0] = m._matData[2][0] * scale._x; + _matData[3][0] = m._matData[3][0] * scale._x; + + _matData[0][1] = m._matData[0][1] * scale._y; + _matData[1][1] = m._matData[1][1] * scale._y; + _matData[2][1] = m._matData[2][1] * scale._y; + _matData[3][1] = m._matData[3][1] * scale._y; + + _matData[0][2] = m._matData[0][2] * scale._z; + _matData[1][2] = m._matData[1][2] * scale._z; + _matData[2][2] = m._matData[2][2] * scale._z; + _matData[3][2] = m._matData[3][2] * scale._z; + + _matData[3][0] = m._matData[3][0]; + _matData[3][1] = m._matData[3][1]; + _matData[3][2] = m._matData[3][2]; + _matData[3][3] = m._matData[3][3]; + + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::translateRotation( const Vector3 & trans ) { + _matData[3][0] = trans._x; + _matData[3][1] = trans._y; + _matData[3][2] = trans._z; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::translateRotationLeft( const Vector3 & trans ) { + _matData[3][0] = _matData[0][0] * trans._x + _matData[1][0] * trans._y + _matData[2][0] * trans._z; + _matData[3][1] = _matData[0][1] * trans._x + _matData[1][1] * trans._y + _matData[2][1] * trans._z; + _matData[3][2] = _matData[0][2] * trans._x + _matData[1][2] * trans._y + _matData[2][2] * trans._z; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::setDiagonal( float v0, float v1, float v2, float v3 ) { + _matData[0][0] = v0; + _matData[1][1] = v1; + _matData[2][2] = v2; + _matData[3][3] = v3; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::setDiagonal( const Vector3 & vec, float v3 ) { + _matData[0][0] = vec._x; + _matData[1][1] = vec._y; + _matData[2][2] = vec._z; + _matData[3][3] = v3; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::product( const Matrix4x4 & m1, const Matrix4x4 & m2 ) { + _matData[0][0] = m1._matData[0][0] * m2._matData[0][0] + m1._matData[0][1] * m2._matData[1][0] + m1._matData[0][2] * m2._matData[2][0] + m1._matData[0][3] * m2._matData[3][0]; + _matData[0][1] = m1._matData[0][0] * m2._matData[0][1] + m1._matData[0][1] * m2._matData[1][1] + m1._matData[0][2] * m2._matData[2][1] + m1._matData[0][3] * m2._matData[3][1]; + _matData[0][2] = m1._matData[0][0] * m2._matData[0][2] + m1._matData[0][1] * m2._matData[1][2] + m1._matData[0][2] * m2._matData[2][2] + m1._matData[0][3] * m2._matData[3][2]; + _matData[0][3] = m1._matData[0][0] * m2._matData[0][3] + m1._matData[0][1] * m2._matData[1][3] + m1._matData[0][2] * m2._matData[2][3] + m1._matData[0][3] * m2._matData[3][3]; + + _matData[1][0] = m1._matData[1][0] * m2._matData[0][0] + m1._matData[1][1] * m2._matData[1][0] + m1._matData[1][2] * m2._matData[2][0] + m1._matData[1][3] * m2._matData[3][0]; + _matData[1][1] = m1._matData[1][0] * m2._matData[0][1] + m1._matData[1][1] * m2._matData[1][1] + m1._matData[1][2] * m2._matData[2][1] + m1._matData[1][3] * m2._matData[3][1]; + _matData[1][2] = m1._matData[1][0] * m2._matData[0][2] + m1._matData[1][1] * m2._matData[1][2] + m1._matData[1][2] * m2._matData[2][2] + m1._matData[1][3] * m2._matData[3][2]; + _matData[1][3] = m1._matData[1][0] * m2._matData[0][3] + m1._matData[1][1] * m2._matData[1][3] + m1._matData[1][2] * m2._matData[2][3] + m1._matData[1][3] * m2._matData[3][3]; + + _matData[2][0] = m1._matData[2][0] * m2._matData[0][0] + m1._matData[2][1] * m2._matData[1][0] + m1._matData[2][2] * m2._matData[2][0] + m1._matData[2][3] * m2._matData[3][0]; + _matData[2][1] = m1._matData[2][0] * m2._matData[0][1] + m1._matData[2][1] * m2._matData[1][1] + m1._matData[2][2] * m2._matData[2][1] + m1._matData[2][3] * m2._matData[3][1]; + _matData[2][2] = m1._matData[2][0] * m2._matData[0][2] + m1._matData[2][1] * m2._matData[1][2] + m1._matData[2][2] * m2._matData[2][2] + m1._matData[2][3] * m2._matData[3][2]; + _matData[2][3] = m1._matData[2][0] * m2._matData[0][3] + m1._matData[2][1] * m2._matData[1][3] + m1._matData[2][2] * m2._matData[2][3] + m1._matData[2][3] * m2._matData[3][3]; + + _matData[3][0] = m1._matData[3][0] * m2._matData[0][0] + m1._matData[3][1] * m2._matData[1][0] + m1._matData[3][2] * m2._matData[2][0] + m1._matData[3][3] * m2._matData[3][0]; + _matData[3][1] = m1._matData[3][0] * m2._matData[0][1] + m1._matData[3][1] * m2._matData[1][1] + m1._matData[3][2] * m2._matData[2][1] + m1._matData[3][3] * m2._matData[3][1]; + _matData[3][2] = m1._matData[3][0] * m2._matData[0][2] + m1._matData[3][1] * m2._matData[1][2] + m1._matData[3][2] * m2._matData[2][2] + m1._matData[3][3] * m2._matData[3][2]; + _matData[3][3] = m1._matData[3][0] * m2._matData[0][3] + m1._matData[3][1] * m2._matData[1][3] + m1._matData[3][2] * m2._matData[2][3] + m1._matData[3][3] * m2._matData[3][3]; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::product3x3( const Matrix4x4 & m1, const Matrix4x4 & m2 ) { + _matData[0][3] = _matData[1][3] = _matData[2][3] = _matData[3][0] = _matData[3][1] = _matData[3][2] = 0.f; + _matData[3][3] = 1.f; + + _matData[0][0] = m1._matData[0][0] * m2._matData[0][0] + m1._matData[0][1] * m2._matData[1][0] + m1._matData[0][2] * m2._matData[2][0]; + _matData[0][1] = m1._matData[0][0] * m2._matData[0][1] + m1._matData[0][1] * m2._matData[1][1] + m1._matData[0][2] * m2._matData[2][1]; + _matData[0][2] = m1._matData[0][0] * m2._matData[0][2] + m1._matData[0][1] * m2._matData[1][2] + m1._matData[0][2] * m2._matData[2][2]; + + _matData[1][0] = m1._matData[1][0] * m2._matData[0][0] + m1._matData[1][1] * m2._matData[1][0] + m1._matData[1][2] * m2._matData[2][0]; + _matData[1][1] = m1._matData[1][0] * m2._matData[0][1] + m1._matData[1][1] * m2._matData[1][1] + m1._matData[1][2] * m2._matData[2][1]; + _matData[1][2] = m1._matData[1][0] * m2._matData[0][2] + m1._matData[1][1] * m2._matData[1][2] + m1._matData[1][2] * m2._matData[2][2]; + + _matData[2][0] = m1._matData[2][0] * m2._matData[0][0] + m1._matData[2][1] * m2._matData[1][0] + m1._matData[2][2] * m2._matData[2][0]; + _matData[2][1] = m1._matData[2][0] * m2._matData[0][1] + m1._matData[2][1] * m2._matData[1][1] + m1._matData[2][2] * m2._matData[2][1]; + _matData[2][2] = m1._matData[2][0] * m2._matData[0][2] + m1._matData[2][1] * m2._matData[1][2] + m1._matData[2][2] * m2._matData[2][2]; + + _matData[3][0] = m1._matData[3][0] * m2._matData[0][0] + m1._matData[3][1] * m2._matData[1][0] + m1._matData[3][2] * m2._matData[2][0]; + _matData[3][1] = m1._matData[3][0] * m2._matData[0][1] + m1._matData[3][1] * m2._matData[1][1] + m1._matData[3][2] * m2._matData[2][1]; + _matData[3][2] = m1._matData[3][0] * m2._matData[0][2] + m1._matData[3][1] * m2._matData[1][2] + m1._matData[3][2] * m2._matData[2][2]; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::setAsTranspose( Matrix4x4 & m1 ) { + _matData[0][0] = m1._matData[0][0]; + _matData[0][1] = m1._matData[1][0]; + _matData[0][2] = m1._matData[2][0]; + _matData[0][3] = m1._matData[3][0]; + + _matData[1][0] = m1._matData[0][1]; + _matData[1][1] = m1._matData[1][1]; + _matData[1][2] = m1._matData[2][1]; + _matData[1][3] = m1._matData[3][1]; + + _matData[2][0] = m1._matData[0][2]; + _matData[2][1] = m1._matData[1][2]; + _matData[2][2] = m1._matData[2][2]; + _matData[2][3] = m1._matData[3][2]; + + _matData[3][0] = m1._matData[0][3]; + _matData[3][1] = m1._matData[1][3]; + _matData[3][2] = m1._matData[2][3]; + _matData[3][3] = m1._matData[3][3]; + } + + /////////////////////////////////////////////////////////////////////////// + + void Matrix4x4::transpose() { + float t; + t = _matData[0][1]; + _matData[0][1] = _matData[1][0]; + _matData[1][0] = t; + t = _matData[0][2]; + _matData[0][2] = _matData[2][0]; + _matData[2][0] = t; + t = _matData[0][3]; + _matData[0][3] = _matData[3][0]; + _matData[3][0] = t; + + t = _matData[1][2]; + _matData[1][2] = _matData[2][1]; + _matData[2][1] = t; + t = _matData[1][3]; + _matData[1][3] = _matData[3][1]; + _matData[3][1] = t; + + t = _matData[2][3]; + _matData[2][3] = _matData[3][2]; + _matData[3][2] = t; + } + + /////////////////////////////////////////////////////////////////////////// + + Logger & operator << ( Logger & out, const Matrix4x4 & mat ) { + out << mat._matData[0][0] << " " << mat._matData[0][1] << " " << mat._matData[0][2] << " " << mat._matData[0][3] << "\n"; + out << mat._matData[1][0] << " " << mat._matData[1][1] << " " << mat._matData[1][2] << " " << mat._matData[1][3] << "\n"; + out << mat._matData[2][0] << " " << mat._matData[2][1] << " " << mat._matData[2][2] << " " << mat._matData[2][3] << "\n"; + out << mat._matData[3][0] << " " << mat._matData[3][1] << " " << mat._matData[3][2] << " " << mat._matData[3][3]; + return out; + } + + /////////////////////////////////////////////////////////////////////////// + } // namespace Math + } // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/Matrix.h b/src/Menge/MengeCore/Math/Matrix.h new file mode 100644 index 00000000..2d1086ae --- /dev/null +++ b/src/Menge/MengeCore/Math/Matrix.h @@ -0,0 +1,305 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Matrix.h + * @brief The definition of a 4x4 transformation matrix. + */ + +#ifndef __MATRIX_H__ +#define __MATRIX_H__ + +#include "CoreConfig.h" +#include "vector.h" +#include +#include + +namespace Menge { + + namespace Math { + /*! + * @brief Basic 4x4 matrix of floats. + * + * Functions predominantly come in the form result.op( operand1, operand2 ) to limit + * implicit data copying. The operations is performed on the parameter, and the + * result is stored in the instance calling the operation. + * + * The data is stored column-major data -- i.e. the data is organized: + * [ [x-axis 0] + * [y-axis 0] + * [z-axis 0] + * [tx ty tz 1] ] + * It's assumed that multiplication with vectors is LEFT-multiplication by row vectors + * i.e. q = p * M (where q & p are vectors and M is matrix). + */ + class MENGE_API Matrix4x4 { + public: + /*! + * @brief Constructor. + * + * This constructor initializes the matrix to be the identity. + */ + Matrix4x4(); + + /*! + * @brief Non-initializing constructor. + * + * By constructing with an arbitrary boolean, the matrix will + * *not* be initialized. + * + * @param garbage The ignored boolean. + */ + Matrix4x4( bool garbage ){} // DOESN'T initialize data + + /*! + * @brief Sets the matrix to the identity matrix. + */ + void identity(); + + /*! + * @brief Index operation. + * + * There is no run-time check on the index values. + * + * @param row The row index (should be in the range [0, 3]). + * @param col The column index (should be in the range [0, 3]). + * @returns The value of the matrix at (row, col). + */ + inline float operator()( int row, int col ) const { return _matData[row][col]; } + + /*! + * @brief Reference index operation. + * + * There is no run-time check on the index values. + * + * @param row The row index (should be in the range [0, 3]). + * @param col The column index (should be in the range [0, 3]). + * @returns A reference to the matrix entry at (row, col). + */ + inline float & operator()( int row, int col ) { return _matData[row][col]; } + + /*! + * @brief Set the values of an entire row of the matrix. + * + * @param row The index of the row to set (should be in the range [0, 3]). + * @param v0 The value for the first column. + * @param v1 The value for the second column. + * @param v2 The value for the third column. + * @param v3 The value for the fourth column. + */ + void setRow( int row, float v0, float v1, float v2, float v3 = 1.f ); + + /*! + * @brief Set the values of an entire row of the matrix. + * + * @param row The index of the row to set (should be in the range [0, 3]). + * @param vec The value for the first, second, and third columns. + * @param v3 The value for the fourth column. + */ + void setRow( int row, const Vector3 & vec, float v3 = 1.f ); + + /*! + * @brief Multiplies the given matrix by an implicit scale matrix + * and stores it here. + * + * The scale vector parameter is , which implicitly defines + * a scale transformation matrix S (with sx, sy, sz, 1 on the diagonal and zeros + * everywhere else). + * We then perform the matrix *left* multiplication: S * m and assign it to this + * matrix. + * + * @param scale A vector of scale amounts along the three axes + * . + * @param m The matrix to scale: perform S * m. + */ + void scale( const Vector3 & scale, Matrix4x4 & m ); + + /*! + * @brief Multiplies the given matrix by an implicit scale matrix + * and stores it here. + * + * The scale vector parameter is , which implicitly defines + * a scale transformation matrix S (with sx, sy, sz, 1 on the diagonal and zeros + * everywhere else). + * We then perform the matrix *right* multiplication: m * S and assign it to this + * matrix. + * + * @param scale A vector of scale amounts along the three axes + * . + * @param m The matrix to scale: perform m * S. + */ + void scaleRight( const Vector3 & scale, Matrix4x4 & m ); + + /*! + * @brief Compute the trace of the 4x4 matrix. + * + * The trace of the matrix is the product of the values on the matrix's diagonal. + * + * @returns The trace of the matrix. + */ + inline float trace() const { + return _matData[0][0] * _matData[1][1] * _matData[2][2] * _matData[3][3]; + }; + + /*! + * @brief Compute the trace of the upper-left 3x3 sub-matrix. + * + * The trace of the matrix is the product of the values on the matrix's diagonal. + * + * @returns The trace of the upper, left 3x3 sub-matrix. + */ + inline float trace3x3() const { + return _matData[0][0] * _matData[1][1] * _matData[2][2]; + }; + + /*! + * @brief Right-multiply this matrix by a translation matrix. + * + * This should *only* be used if this matrix is known to have the vector <0,0,0,1> in + * both the last row and the last column. This method exploits that knowledge to + * perform the matrix multiplication efficiently. + * The result of the multiplication is written in place. + * Essentially, this is an optimized version of M = M * T. + * Where T is *almost* the identity matrix, but with on the bottom row. + * + * @param trans The translation vector + */ + void translateRotation( const Vector3 & trans ); + + /*! + * @brief Left-multiply this matrix by a translation matrix. + * + * This should *only* be used if this matrix is known to have the vector <0,0,0,1> in + * both the last row and the last column. This method exploits that knowledge to + * perform the matrix multiplication efficiently. + * The result of the multiplication is written in place. + * Essentially, this is an optimized version of M = T * M. + * Where T is *almost* the identity matrix, but with on the bottom row. + * + * @param trans The translation vector + */ + void translateRotationLeft( const Vector3 & trans ); + + /*! + * @brief Sets the diagonal to the given values. + * + * @param v0 The value for M[0, 0]. + * @param v1 The value for M[1, 1]. + * @param v2 The value for M[2, 2]. + * @param v3 The value for M[3, 3]. + */ + void setDiagonal( float v0, float v1, float v2, float v3 = 1.f ); + + /*! + * @brief Sets the diagonal to the given values. + * + * @param vec The values for M[0, 0], M[1, 1], and M[2, 2]. + * @param v3 The value for M[3, 3]. + */ + void setDiagonal( const Vector3 & vec, float v3 = 1.f ); + + /*! + * @brief Performs the matrix product and stores the result in this + * matrix. + * + * Computes the 4x4 matrix product: m1 * m2 + * + * @param m1 The left-hand matrix. + * @param m2 The right-hand matrix. + */ + void product( const Matrix4x4 & m1, const Matrix4x4 & m2 ); + + /*! + * @brief Computes a 3x3 matrix multiplication on the inputs + * storing the result in this matrix. + * + * Computes the 3x3 matrix product: m1 * m2. + * The final column and row of this matrix are set to the vector + * <0, 0, 0, 1>. + * + * @param m1 The left-hand matrix. + * @param m2 The right-hand matrix. + */ + void product3x3( const Matrix4x4 & m1, const Matrix4x4 & m2 ); + + /*! + * @brief Set this matrix to be the transpose of the given matrix. + * + * @param m1 The matrix whose transpose is stored in this matrix. + */ + void setAsTranspose( Matrix4x4 & m1 ); + + /*! + * @brief Transpose this matrix in-place. + */ + void transpose(); + + /*! + * @brief Ouput the string-formatted matrix to an output stream. + * + * @param out The output stream. + * @param mat The matrix. + * @returns A reference to the output stream. + */ + friend Logger & operator << ( Logger & out, const Matrix4x4 & mat ); + + /*! + * @brief Get a pointer to the underlying data as a flat array. + * + * @returns A pointer to the underlying, column-major data. + */ + inline float * getFlattened() { return _flatData; } + + private: + /*! + * @union MatrixData + * @brief The underlying matrix data. + */ + union { + float _flatData[16]; ///< The data represented as a flat array. + float _matData[4][4]; ///< The data represented as a 2D array. + }; + }; + + /*! + * @brief A convenenient identity matrix. + */ + extern MENGE_API Matrix4x4 IDENTITY4x4; + } // namespace Math +} // namespace Menge +#endif // __MATRIX_H__ diff --git a/src/Menge/MengeCore/Math/RandGenerator.cpp b/src/Menge/MengeCore/Math/RandGenerator.cpp new file mode 100644 index 00000000..c5743df1 --- /dev/null +++ b/src/Menge/MengeCore/Math/RandGenerator.cpp @@ -0,0 +1,699 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "RandGenerator.h" +#include "SimRandom.h" +#include "tinyxml/tinyxml.h" +#include +#include + +#ifdef _WIN32 +#define NOMINMAX // prevent windows.h from stomping on "max" - used by limits +#include "windows.h" +#else // _WIN32 +#include +#include "include/macros.h" +#endif // _WIN32 + +namespace Menge { + + namespace Math { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Default Seed Generator + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The global seed for the number generators. + * + * If the seed is zero, the number generators will get a + * unique seed based on the system clock. If it is non-zero + * they will get this seed (unless they locally override it + * explicitly). + */ + int GLOBAL_SEED = 0; + + /*! + * @brief The number of generators that have been created. + * This is used to create a constant, fixed variety. + * If every generator gets exactly the same seed, then + * the results are strongly correlated. By incrementing + * the seed by the number of times the getSeed is called + * it guarantees uncorrelated pseudo-random sequences. + */ + int SEED_REQUESTS = 0; + + ///////////////////////////////////////////////////////////////////// + + void setDefaultGeneratorSeed( int seed ) { + GLOBAL_SEED = seed; + } + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Based on the default seed state, return a random + * generator seed. + * + * @returns A seed for a number generator. + */ + int getDefaultSeed() { + if ( GLOBAL_SEED ) { + return GLOBAL_SEED + ++SEED_REQUESTS; + } else { + #ifdef _WIN32 + __int64 t; + ::QueryPerformanceCounter( (LARGE_INTEGER*) &t ); + return static_cast< int >( t ); + #else + struct timespec t; + clock_gettime( CLOCK_REALTIME, &t ); + return static_cast< int >( t.tv_nsec ); + #endif + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstFloatGenerator + ///////////////////////////////////////////////////////////////////// + + void ConstFloatGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + FloatGenerator * ConstFloatGenerator::copy() const { + return new ConstFloatGenerator( _value ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const ConstFloatGenerator & gen ) { + out << "Const float: value( " << gen._value << " )"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NormalFloatGenerator + ///////////////////////////////////////////////////////////////////// + + NormalFloatGenerator::NormalFloatGenerator( float mean, float stddev, float minVal, float maxVal, int seed ):FloatGenerator(), _mean(mean),_std(stddev),_min(minVal),_max(maxVal),_second(0.f),_calls(0) { + if ( seed == 0 ) { + _seed = getDefaultSeed(); + } else { + _seed = seed; + } + } + + ///////////////////////////////////////////////////////////////////// + + void NormalFloatGenerator::set( float mean, float stddev, float minVal, float maxVal ) { + _mean = mean; + _std = stddev; + _min = minVal; + _max = maxVal; + _calls = 0; + _seed = getDefaultSeed(); + } + + ///////////////////////////////////////////////////////////////////// + + float NormalFloatGenerator::getValue() const { + float val; + if ( _calls % 2 == 0 ) { // Generate new values + r4_normalR( _mean, _std, val, _second, &_seed ); + } else { // simply return second value + val = _second; + } + ++_calls; + + if ( val < _min ) val = _min; + else if ( val > _max ) val = _max; + + return val; + } + + ///////////////////////////////////////////////////////////////////// + + float NormalFloatGenerator::getValueConcurrent() const { + _lock.lock(); + float value = getValue(); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + void NormalFloatGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + FloatGenerator * NormalFloatGenerator::copy() const { + return new NormalFloatGenerator( _mean, _std, _min, _max, _seed + 1 ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const NormalFloatGenerator & gen ) { + out << "Normal float: mean( " << gen._mean << " ), std( " << gen._std << " ) in the range [ " << gen._min << ", " << gen._max << " ]"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of UniformFloatGenerator + ///////////////////////////////////////////////////////////////////// + + UniformFloatGenerator::UniformFloatGenerator( float minVal, float maxVal, int seed ):FloatGenerator(), _min(minVal),_size(maxVal-minVal) { + if ( seed == 0 ) { + _seed = getDefaultSeed(); + } else { + _seed = seed; + } + } + + ///////////////////////////////////////////////////////////////////// + + UniformFloatGenerator::UniformFloatGenerator( const UniformFloatGenerator & gen ):FloatGenerator(gen), _min(gen._min), _size(gen._size), _seed(gen._seed+1) { + } + + ///////////////////////////////////////////////////////////////////// + + float UniformFloatGenerator::getValue() const { + return _min + r4_uniform_01( &_seed ) * _size; + } + + ///////////////////////////////////////////////////////////////////// + + float UniformFloatGenerator::getValueConcurrent() const { + _lock.lock(); + float value = getValue(); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + void UniformFloatGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + FloatGenerator * UniformFloatGenerator::copy() const { + return new UniformFloatGenerator( _min, _min + _size, _seed + 1 ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const UniformFloatGenerator & gen ) { + out << "Uniform float: range[ " << gen._min << " , " << (gen._min + gen._size ) << " ]"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of ConstIntGenerator + ///////////////////////////////////////////////////////////////////// + + void ConstIntGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + IntGenerator * ConstIntGenerator::copy() const { + return new ConstIntGenerator( _value ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const ConstIntGenerator & gen ) { + out << "Const int: value( " << gen._value << " )"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of UniformIntGenerator + ///////////////////////////////////////////////////////////////////// + + UniformIntGenerator::UniformIntGenerator( int minVal, int maxVal, int seed ):IntGenerator(), _min(minVal),_size(maxVal-minVal+1),_seed(seed) { + if ( seed == 0 ) { + _seed = getDefaultSeed(); + } else { + _seed = seed; + } + } + + ///////////////////////////////////////////////////////////////////// + + int UniformIntGenerator::getValue() const { + int randVal = static_cast< int >( r4_uniform_01( &_seed ) * std::numeric_limits::max() ); + int val = randVal % _size; + return _min + val; + } + + ///////////////////////////////////////////////////////////////////// + + int UniformIntGenerator::getValueConcurrent() const { + _lock.lock(); + int value = getValue(); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + void UniformIntGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + IntGenerator * UniformIntGenerator::copy() const { + return new UniformIntGenerator( _min, _min + _size, _seed + 1 ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const UniformIntGenerator & gen ) { + out << "Uniform int: range[ " << gen._min << " , " << (gen._min + gen._size - 1) << " ]"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of Zero2DGenerator + ///////////////////////////////////////////////////////////////////// + + void Zero2DGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const Zero2DGenerator & gen ) { + out << "ZERO 2D Generator"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of Const2DGenerator + ///////////////////////////////////////////////////////////////////// + + void Const2DGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const Const2DGenerator & gen ) { + out << "Const 2D Generator: value = " << gen._value; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of AABBUniformPosGenerator + ///////////////////////////////////////////////////////////////////// + + AABBUniformPosGenerator::AABBUniformPosGenerator( const Vector2 & minPt, const Vector2 & maxPt, int seed ):Vec2DGenerator(), _xRand(minPt.x(),maxPt.x(),seed==0?getDefaultSeed():seed), _yRand(minPt.y(), maxPt.y(),(seed==0?getDefaultSeed():seed)+5) { + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 AABBUniformPosGenerator::getValue() const { + return Vector2( _xRand.getValue(), _yRand.getValue() ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 AABBUniformPosGenerator::getValueConcurrent() const { + _lock.lock(); + Vector2 value( _xRand.getValue(), _yRand.getValue() ); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + AABBUniformPosGenerator::AABBUniformPosGenerator( const AABBUniformPosGenerator & aabbGen ): _xRand(aabbGen._xRand), _yRand(aabbGen._yRand) { + } + + ///////////////////////////////////////////////////////////////////// + + Vec2DGenerator * AABBUniformPosGenerator::copy() const { + return new AABBUniformPosGenerator( *this ); + } + + ///////////////////////////////////////////////////////////////////// + + void AABBUniformPosGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const AABBUniformPosGenerator & gen ) { + out << "Uniform in AABB: "; + out << "x: " << gen._xRand << ", y: " << gen._yRand; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of OBBUniformPosGenerator + ///////////////////////////////////////////////////////////////////// + + OBBUniformPosGenerator::OBBUniformPosGenerator( const Vector2 & minPt, const Vector2 & size, float theta, int seed ):Vec2DGenerator(), _xRand(0.f, size.x(),seed==0?getDefaultSeed():seed), _yRand(0.f, size.y(),(seed==0?getDefaultSeed():seed)+5), _minPt(minPt), _cosTheta(cos(theta)), _sinTheta(sin(theta)) { + } + + ///////////////////////////////////////////////////////////////////// + + OBBUniformPosGenerator::OBBUniformPosGenerator( const OBBUniformPosGenerator & obbGen ): _xRand(obbGen._xRand), _yRand(obbGen._yRand), _minPt(obbGen._minPt), _cosTheta(obbGen._cosTheta), _sinTheta(obbGen._sinTheta) { + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 OBBUniformPosGenerator::getValue() const { + Vector2 inRect( _xRand.getValue(), _yRand.getValue() ); + // rotate + const float x = inRect.x() * _cosTheta - inRect.y() * _sinTheta + _minPt.x(); + const float y = inRect.y() * _cosTheta + inRect.x() * _sinTheta + _minPt.y(); + return Vector2( x, y ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 OBBUniformPosGenerator::getValueConcurrent() const { + _lock.lock(); + Vector2 value( getValue() ); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + Vec2DGenerator * OBBUniformPosGenerator::copy() const { + return new OBBUniformPosGenerator( *this ); + } + + ///////////////////////////////////////////////////////////////////// + + void OBBUniformPosGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const OBBUniformPosGenerator & gen ) { + out << "Uniform in OBB:"; + out << " x: " << gen._xRand << ", y: " << gen._yRand; + out << ", minPt: " << gen._minPt; + out << ", theta: " << atan2( gen._sinTheta, gen._cosTheta ); + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of WeightedInt + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const WeightedInt & wInt ) { + out << wInt._val << "( " << wInt._wt << " )"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of WeightedIntGenerator + ///////////////////////////////////////////////////////////////////// + + WeightedIntGenerator::WeightedIntGenerator():IntGenerator(), _dice(0.f,1.f,getDefaultSeed()), _pairs() { + } + + ///////////////////////////////////////////////////////////////////// + + WeightedIntGenerator::WeightedIntGenerator( const WeightedIntGenerator & gen):IntGenerator(), _dice(gen._dice) { + _pairs.insert( _pairs.begin(), gen._pairs.begin(), gen._pairs.end() ); + } + + ///////////////////////////////////////////////////////////////////// + + int WeightedIntGenerator::getValue() const { + size_t pCount = _pairs.size(); + float t = _dice.getValue(); + float start = 0.f; + for ( size_t i = 0; i < pCount; ++i ) { + float end = _pairs[i]._wt; + if ( t >= start && t < end ) { + return _pairs[i]._val; + } + } + return _pairs[ pCount - 1 ]._val; + } + + ///////////////////////////////////////////////////////////////////// + + int WeightedIntGenerator::getValueConcurrent() const { + _lock.lock(); + int value = getValue(); + _lock.release(); + return value; + } + + ///////////////////////////////////////////////////////////////////// + + void WeightedIntGenerator::addValue(int value, float weight) { + _pairs.push_back( WeightedInt( value, weight ) ); + } + + ///////////////////////////////////////////////////////////////////// + + void WeightedIntGenerator::finalize() { + size_t pCount = _pairs.size(); + float sum = 0.f; + for ( size_t i = 0; i < pCount; ++i ) { + sum += _pairs[i]._wt; + } + sum = 1.f / sum; + for ( size_t i = 0; i < pCount; ++i ) { + _pairs[i]._wt *= sum; + if ( i > 0 ) { + _pairs[i]._wt += _pairs[i-1]._wt; + } + } + } + + ///////////////////////////////////////////////////////////////////// + + void WeightedIntGenerator::print( Logger & out ) const { + out << (*this); + } + + ///////////////////////////////////////////////////////////////////// + + IntGenerator * WeightedIntGenerator::copy() const { + return new WeightedIntGenerator( *this ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & out, const WeightedIntGenerator & gen ) { + out << "Weighted int generator:"; + std::vector< WeightedInt >::const_iterator itr = gen._pairs.begin(); + for ( ; itr != gen._pairs.end(); ++itr ) { + out << ", " << (*itr); + } + return out; + } + + ///////////////////////////////////////////////////////////////////// + + // Given an xml node which SHOULD have the definition of a 2D generator, this + // instantiates one + Vec2DGenerator * create2DGenerator( TiXmlElement * node, float scale ) { + int seed = getDefaultSeed(); + Vec2DGenerator * gen = 0x0; + const char * genCStr = node->Attribute( "dist" ); + if ( genCStr == 0x0 ) { + logger << Logger::WARN_MSG << "Missing the \"dist\" attribute on line " << node->Row() << "\n"; + return 0x0; + } + std::string genType( genCStr ); + if ( genType == "n" ) { + logger << Logger::ERR_MSG << "Normal 2D generators not supported yet!\n"; + } else if ( genType == "u" ) { + double minX, maxX, minY, maxY; + if ( ! node->Attribute( "min_x", &minX ) ) { + logger << Logger::ERR_MSG << "Uniform 2D distributon requires \"min_x\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( "max_x", &maxX ) ) { + logger << Logger::ERR_MSG << "Uniform 2D distributon requires \"max_x\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( "min_y", &minY ) ) { + logger << Logger::ERR_MSG << "Uniform 2D distributon requires \"min_y\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( "max_y", &maxY ) ) { + logger << Logger::ERR_MSG << "Uniform 2D distributon requires \"max_y\" attribute.\n"; + return gen; + } + node->Attribute( "seed", &seed ); + gen = new AABBUniformPosGenerator( Vector2( (float)minX * scale, (float)minY * scale ), Vector2( (float)maxX * scale, (float)maxY * scale ), seed ); + } else if ( genType == "c" ) { + double x, y; + if ( ! node->Attribute( "x_value", &x ) ) { + logger << Logger::ERR_MSG << "Constant 2D distributon requires \"x_value\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( "y_value", &y ) ) { + logger << Logger::ERR_MSG << "Constant 2D distributon requires \"y_value\" attribute.\n"; + return gen; + } + gen = new Const2DGenerator( Vector2( (float)x * scale, (float)y * scale ) ); + } else if ( genType == "" ) { + logger << Logger::ERR_MSG << "No 2D number generation type specified. Should be u or c.\n"; + } else { + logger << Logger::ERR_MSG << "Unrecognized 2D number generation type: " << genType << "\n"; + } + return gen; + } + + ///////////////////////////////////////////////////////////////////// + + FloatGenerator * createFloatGenerator( TiXmlElement * node, float scale, const std::string & prefix ) { + FloatGenerator * gen = 0x0; + std::string distS = prefix + "dist"; + const char * genCStr = node->Attribute( distS.c_str() ); + if ( genCStr == 0x0 ) { + logger << Logger::WARN_MSG << "Missing the \"dist\" attribute on line " << node->Row() << "\n"; + return 0x0; + } + std::string genType( genCStr ); + + if ( genType == "n" ) { + double mean, std; + if ( ! node->Attribute( prefix + "mean", &mean ) ) { + logger << Logger::ERR_MSG << "Normal distribution requires \"mean\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( prefix + "stddev", &std ) ) { + logger << Logger::ERR_MSG << "Normal distribution requires \"stddev\" attribute.\n"; + return gen; + } + int seed; + if ( !node->Attribute( prefix + "seed", &seed ) ) { + seed = getDefaultSeed(); + } + mean *= scale; + std *= scale; + double minVal = mean - 3.f * std; + double maxVal = mean + 3.f * std; + gen = new NormalFloatGenerator( (float)mean, (float)std, (float)minVal, (float)maxVal, seed ); + } else if ( genType == "u" ) { + double minVal, maxVal; + if ( ! node->Attribute( prefix + "min", &minVal ) ) { + logger << Logger::ERR_MSG << "Uniform distribution requires \"min\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( prefix + "max", &maxVal ) ) { + logger << Logger::ERR_MSG << "Uniform distribution requires \"max\" attribute.\n"; + return gen; + } + int seed; + if ( !node->Attribute( prefix + "seed", &seed ) ) { + seed = getDefaultSeed(); + } + minVal *= scale; + maxVal *= scale; + gen = new UniformFloatGenerator( (float)minVal, (float)maxVal, seed ); + } else if ( genType == "c" ) { + double val; + if ( ! node->Attribute( prefix + "value", &val ) ) { + logger << Logger::ERR_MSG << "Constant distribution requires \"value\" attribute.\n"; + return gen; + } + gen = new ConstFloatGenerator( (float)val * scale ); + } else if ( genType == "" ) { + logger << Logger::ERR_MSG << "Float generation requires a type: n, c or u.\n"; + } else { + logger << Logger::ERR_MSG << "Unrecognized float generation type: " << genType << "\n"; + } + return gen; + } + + ///////////////////////////////////////////////////////////////////// + + IntGenerator * createIntGenerator( TiXmlElement * node, const std::string & prefix ) { + int seed = getDefaultSeed(); + + IntGenerator * gen = 0x0; + std::string distS = prefix + "dist"; + const char * genCStr = node->Attribute( distS.c_str() ); + if ( genCStr == 0x0 ) { + logger << Logger::WARN_MSG << "Missing the \"dist\" attribute on line " << node->Row() << "\n"; + return 0x0; + } + std::string genType( genCStr ); + if ( genType == "u" ) { + int minVal, maxVal; + if ( ! node->Attribute( prefix + "min", &minVal ) ) { + logger << Logger::ERR_MSG << "Uniform distribution requires \"min\" attribute.\n"; + return gen; + } + if ( ! node->Attribute( prefix + "max", &maxVal ) ) { + logger << Logger::ERR_MSG << "Uniform distribution requires \"max\" attribute.\n"; + return gen; + } + node->Attribute( "seed", &seed ); + gen = new UniformIntGenerator( minVal, maxVal, seed ); + } else if ( genType == "c" ) { + int val; + if ( ! node->Attribute( prefix + "value", &val ) ) { + logger << Logger::ERR_MSG << "Constant distribution requires \"value\" attribute.\n"; + return gen; + } + gen = new ConstIntGenerator( val ); + } else if ( genType == "" ) { + logger << Logger::ERR_MSG << "Int generation requires a distribution type: c or u.\n"; + } else { + logger << Logger::ERR_MSG << "Unrecognized int generation type: " << genType << ". Must be c or u.\n"; + } + return gen; + } + } // namespace Math +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/RandGenerator.h b/src/Menge/MengeCore/Math/RandGenerator.h new file mode 100644 index 00000000..7b5d66b2 --- /dev/null +++ b/src/Menge/MengeCore/Math/RandGenerator.h @@ -0,0 +1,1239 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file RandGenerator.h + * @brief Utility for generating number distributions. + * + * Number generators simple purpose is to produce a value, scalar or vector, + * float or int. These values may be constant or random with either normal + * or uniform distributions. The number generator provides an interface + * so that the various entities do not need to know anything about the + * value type or distribution. + * + * When pointers to number generators are passed around, "ownership" never + * changes. I.e., the caller is still responsible for the eventually freeing + * up the memory. If the callee needs to save an instance of the generator + * (rather than simply just using it to obtain a value) it is responsible + * for calling the copy method to obtain its own unique copy. It is then + * responsible for freeing up that copy. + */ + +#ifndef __RAND_GENERATOR_H__ +#define __RAND_GENERATOR_H__ + +#include "CoreConfig.h" +#include "vector.h" +#include +#include +#include "SimpleLock.h" + +// Forward Declarations +class TiXmlElement; + +namespace Menge { + + namespace Math { + /*! + * @brief Allows the global random number seed value to be set. + * + * This allows a bit more control over the random number generator. Setting + * the global seed value to zero will cause the default seed value to be + * "randomly" generated from the system clock. This will cause repeated + * executions of the program to vary. + * + * Setting the seed to a non-zero constant will still allow for pseudo-random + * distribution of values, but the pattern of distributions will be the same. + * Two different non-zero values will lead to two different, but repeatable, + * distributions. + * + * @param seed The desired seed. + */ + MENGE_API void setDefaultGeneratorSeed( int seed ); + + /*! + * @brief Retrieves a seed based on the global settings + * + * @returns A random seed according to global parameters. + */ + MENGE_API int getDefaultSeed(); + + /*! + * @brief Generic *abstract* class which generates a scalar float value + */ + class MENGE_API FloatGenerator { + public: + /*! + * @brief Constructor. + */ + FloatGenerator(){} + + /*! + * @brief Virtual destructor. + */ + virtual ~FloatGenerator(){} + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * This *must* be overridden by each derived class to provide a string format + * of the float generator. + * + * This method is used instead of the traditional method of writing a + * friend overloaded operator (>>). The reason for this is that using pointers to + * this base class to refer to derived classes would need to be derefenced to pass + * (as objects) to the output stream and dereferencing them precludes the use of + * polymorphism in the format. + * + * This could be overcome by writing the streaming operator to operate on + * a pointer to the base class, which in turn calls a virtual function. But this + * approach removes one level of indirection, and preserves the ability to output + * pointer addresses for the sake of debugging. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const = 0; + + /*! + * @brief Return a value based on the float generation rules. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A float value. + */ + virtual float getValue() const = 0; + + /*! + * @brief Return a value based on the float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A float value. + */ + virtual float getValueConcurrent() const = 0; + + /*! + * @brief Create a copy of itself + * + * This is the basic functionality that must be overwridden by derived classes. + * This is not an exact copy. The copy should not have the same seed as the + * original. All other parameters should be identical. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual FloatGenerator * copy() const = 0; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A FloatGenerator which returns a constant value. + */ + class MENGE_API ConstFloatGenerator : public FloatGenerator { + public: + /*! + * @brief Constructor. + * + * @param value The constant value this generator returns. + */ + ConstFloatGenerator( float value ):FloatGenerator(), _value(value){} + + /*! + * @brief Return a value based on the float generation rules. + * + * @return A constant float value. + */ + virtual float getValue() const { return _value; } + + /*! + * @brief Return a value based on the float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A float value. + */ + virtual float getValueConcurrent() const { return _value; } + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual FloatGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const ConstFloatGenerator & gen ); + + protected: + /*! + * @brief The generator's constant value. + */ + float _value; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A FloatGenerator which returns a normally distributed value. + * + * Furthermore, the normally distributed value is clamped to a range [min, max] that + * prevents the otherwise theoretically possible (though highly improbable) values that + * can lie outside of practical ranges. + * + * The min and max values should span a range which includes the interval: + * [ mean - 3 * std. dev., mean + 3 * std. dev.] + * Clamping the range smaller will lead to abnormal accretions of samples at the clamping + * boundaries. By having the range span at least six standard deviations, centered at the + * mean, most of the normal distribution will be unaffected by clamping. + */ + class MENGE_API NormalFloatGenerator : public FloatGenerator { + public: + /*! + * @brief Constructor. + * + * The value is normally distributed around mean, with a standard deviation of stddev + * but clamped to lie within the range [minVal, maxVal]. + * + * @param mean The mean value of the distribution. + * @param stddev The standard deviation of the value + * @param minVal The lower clamped value, such that all values returned will be + * greater than or equal to minVal. For largely "pure" normal + * distribution, minVal <= mean - 3 * stddev. + * @param maxVal The upper clamped value, such that all values returned will be + * less than or equal to maxVal. For largely "pure" normal + * distribution, maxVal >= mean + 3 * stddev. + * @param seed If the seed is zero, the global seed will be used otherwise + * the particular seed will be used. + */ + NormalFloatGenerator( float mean, float stddev, float minVal, float maxVal, int seed=0 ); + + /*! + * @brief Sets the distribution parameters. + * + * @param mean The mean value of the distribution. + * @param stddev The standard deviation of the value + * @param minVal The lower clamped value, such that all values returned will be + * greater than or equal to minVal. For largely "pure" normal + * distribution, minVal <= mean - 3 * stddev. + * @param maxVal The upper clamped value, such that all values returned will be + * less than or equal to maxVal. For largely "pure" normal + * distribution, maxVal >= mean + 3 * stddev. + */ + void set( float mean, float stddev, float minVal, float maxVal ); + + /*! + * @brief Return a value based on the float generation rules. + * + * @return A clamped, normally-distributed float value. + */ + virtual float getValue() const; + + /*! + * @brief Return a value based on the float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A float value. + */ + virtual float getValueConcurrent() const; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual FloatGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const NormalFloatGenerator & gen ); + + protected: + /*! + * @brief The mean value of the distribution. + */ + float _mean; + + /*! + * @brief The standard deviation of the value + */ + float _std; + + /*! + * @brief The lower clamped value, such that all values returned will be + * greater than or equal to minVal. For largely "pure" normal + * distribution, minVal <= mean - 3 * stddev. + */ + float _min; + /*! + * @brief The upper clamped value, such that all values returned will be + * less than or equal to maxVal. For largely "pure" normal + * distribution, maxVal >= mean + 3 * stddev. + */ + float _max; + + /*! + * @brief The second random number generated (see Math::r4_normalR). + */ + mutable float _second; + + /*! + * @brief The number of calls to the generator. Every second call requires + * a new call to the random number generator. + */ + mutable unsigned int _calls; + + /*! + * @brief A seed for the random number generator. + */ + mutable int _seed; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A FloatGenerator which returns a uniformly distributed value within + * a defined range. + */ + class MENGE_API UniformFloatGenerator : public FloatGenerator { + public: + /*! + * @brief Constructor. + * + * The value will lie within the range [minVal, maxVal]. All values in + * that range have equal probability of being selected. + * + * @param minVal The lower end of the valid range. + * @param maxVal The upper end of the valid range. + * @param seed If the seed is zero, the global seed will be used otherwise + * the particular seed will be used. + */ + UniformFloatGenerator( float minVal, float maxVal, int seed=0 ); + + /*! + * @brief Copy constructor + * + * The copy is not a perfect copy - the seed value in the new + * float generator is NOT the same as the source. + * @param gen The generator to copy + */ + UniformFloatGenerator( const UniformFloatGenerator & gen ); + + /*! + * @brief Return a value based on the float generation rules. + * + * @return A clamped, uniformly-distributed float value. + */ + virtual float getValue() const; + + /*! + * @brief Return a value based on the float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A float value. + */ + virtual float getValueConcurrent() const; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual FloatGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const UniformFloatGenerator & gen ); + + /*! + * @brief Reports the lower end of the valid range. + * + * @returns The lower end of the valid range. + */ + float getMin() const { return _min; } + + /*! + * @brief Reports the upper end of the valid range. + * + * @returns The upper end of the valid range. + */ + float getMax() const { return _min + _size; } + + /*! + * @brief Reports the size of the interval. + * + * @returns The size of the interval. + */ + float getSize() const { return _size; } + + protected: + /*! + * @brief The lower end of the valid range. + */ + float _min; + + /*! + * @brief The size of the valid range. + */ + float _size; + + /*! + * @brief A seed for the random number generator. + */ + mutable int _seed; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Generic *abstract* class which generates a scalar integer value + */ + class MENGE_API IntGenerator { + public: + /*! + * @brief Constructor. + */ + IntGenerator() {} + + /*! + * @brief Virtual destructor. + */ + virtual ~IntGenerator() {} + + /*! + * @brief Return a value based on the integer generation rules. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return An integer value. + */ + virtual int getValue() const = 0; + + /*! + * @brief Return a value based on the integer generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A integer value. + */ + virtual int getValueConcurrent() const = 0; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * This *must* be overridden by each derived class to provide a string format + * of the float generator. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const = 0; + + /*! + * @brief Create a copy of itself + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual IntGenerator * copy() const = 0; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief An IntGenerator which returns a constant value. + */ + class MENGE_API ConstIntGenerator : public IntGenerator { + public: + /*! + * @brief Constructor. + * + * @param value The constant value this generator returns. + */ + ConstIntGenerator( int value ): IntGenerator(),_value(value) {} + + /*! + * @brief Return a value based on the integer generation rules. + * + * @return A constant integer value. + */ + virtual int getValue() const { return _value; } + + /*! + * @brief Return a value based on the integer generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A integer value. + */ + virtual int getValueConcurrent() const { return _value; } + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual IntGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const ConstIntGenerator & gen ); + + + protected: + /*! + * @brief The generator's constant value. + */ + int _value; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief An IntGenerator which returns a uniformly distributed value within + * a defined range. + */ + class MENGE_API UniformIntGenerator : public IntGenerator { + public: + /*! + * @brief Constructor. + * + * The value will lie within the range [minVal, maxVal]. All values in + * that range have equal probability of being selected. + * + * @param minVal The lower end of the valid range. + * @param maxVal The upper end of the valid range. + * @param seed If the seed is zero, the global seed will be used otherwise + * the particular seed will be used. + */ + UniformIntGenerator( int minVal, int maxVal, int seed=0 ); + + /*! + * @brief Set the selection range. + * + * @param minVal The lower end of the valid range. + * @param maxVal The upper end of the valid range. + */ + void setRange( int minVal, int maxVal ) { _min = minVal; _size = maxVal - minVal + 1; } + + /*! + * @brief Return a value based on the integer generation rules. + * + * @return A uniformly distributed integer value. + */ + virtual int getValue() const; + + /*! + * @brief Return a value based on the integer generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A integer value. + */ + virtual int getValueConcurrent() const; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual IntGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const UniformIntGenerator & gen ); + + protected: + /*! + * @brief The lower end of the valid range. + */ + int _min; + + /*! + * @brief The size of the valid range. + */ + int _size; + + /*! + * @brief A seed for the random number generator. + */ + mutable int _seed; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Generic *abstract* class which generates a 2D vector float values + */ + class MENGE_API Vec2DGenerator { + public: + /*! + * @brief Constructor. + */ + Vec2DGenerator() {} + + /*! + * @brief Virtual destructor. + */ + virtual ~Vec2DGenerator(){} + + /*! + * @brief Return a value based on the 2D float generation rules. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValue() const = 0; + + /*! + * @brief Return a value based on the 2D float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValueConcurrent() const = 0; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * This *must* be overridden by each derived class to provide a string format + * of the float generator. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const = 0; + + /*! + * @brief Create a copy of itself + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual Vec2DGenerator * copy() const = 0; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A 2D float generator which always returns a zero. + */ + class MENGE_API Zero2DGenerator : public Vec2DGenerator { + public: + /*! + * @brief Return a value based on the 2D float generation rules. + * + * @return A 2D zero vector. + */ + virtual Vector2 getValue() const { return Vector2(0.f, 0.f); } + + /*! + * @brief Return a value based on the 2D float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValueConcurrent() const { return Vector2(0.f, 0.f); } + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual Vec2DGenerator * copy() const { return new Zero2DGenerator(); } + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const Zero2DGenerator & gen ); + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A 2D float generator which always returns a constant 2D vector. + */ + class MENGE_API Const2DGenerator : public Vec2DGenerator { + public: + /*! + * @brief Constructor. + * + * @param val The value to be returned. + */ + Const2DGenerator( const Vector2 & val ): Vec2DGenerator(), _value(val) {} + + /*! + * @brief Return a value based on the 2D float generation rules. + * + * @return A constat 2D value. + */ + virtual Vector2 getValue() const { return _value; } + + /*! + * @brief Return a value based on the 2D float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValueConcurrent() const { return _value; } + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual Vec2DGenerator * copy() const { return new Const2DGenerator( _value ); } + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const Const2DGenerator & gen ); + + protected: + /*! + * @brief The constant value to return. + */ + Vector2 _value; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Generates a 2D float value uniformly distributed in an axis-aligned box (AAB). + */ + class MENGE_API AABBUniformPosGenerator : public Vec2DGenerator { + public: + /*! + * @brief Constructor. + * + * @param minPt The minimum extent of the AAB. + * @param maxPt The maximum extent of the AAB. + * @param seed If the seed is zero, the global seed will be used otherwise + * the particular seed will be used. + */ + AABBUniformPosGenerator( const Vector2 & minPt, const Vector2 & maxPt, int seed=0 ); + + /*! + * @brief Copy constructor. + * + * @param aabbGen The generator to copy its values from. + */ + AABBUniformPosGenerator( const AABBUniformPosGenerator & aabbGen ); + + /*! + * @brief Return a value based on the 2D float generation rules. + * + * @return A constat position uniformly samples from an AAB. + */ + virtual Vector2 getValue() const; + + /*! + * @brief Return a value based on the 2D float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValueConcurrent() const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual Vec2DGenerator * copy() const; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const AABBUniformPosGenerator & gen ); + protected: + /*! + * @brief The random selector for the x-position of the return value. + */ + UniformFloatGenerator _xRand; + + /*! + * @brief The random selector for the y-position of the return value. + */ + UniformFloatGenerator _yRand; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Generates a 2D float value uniformly distributed in an oriented box (OB). + */ + class MENGE_API OBBUniformPosGenerator : public Vec2DGenerator { + public: + /*! + * @brief Constructor. + * + * @param minPt The anchor point of the OB. + * @param size The size of the OB. + * @param theta The rotation around the achor point (in degrees) of the OB. + * @param seed If the seed is zero, the global seed will be used otherwise + * the particular seed will be used. + */ + OBBUniformPosGenerator( const Vector2 & minPt, const Vector2 & size, float theta, int seed=0 ); + + /*! + * @brief Copy constructor. + * + * @param obbGen The generator to copy its values from. + */ + OBBUniformPosGenerator( const OBBUniformPosGenerator & obbGen ); + + /*! + * @brief Return a value based on the 2D float generation rules. + * + * @return A constat position uniformly samples from an OB. + */ + virtual Vector2 getValue() const; + + /*! + * @brief Return a value based on the 2D float generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A 2D float value. + */ + virtual Vector2 getValueConcurrent() const; + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual Vec2DGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const OBBUniformPosGenerator & gen ); + + protected: + /*! + * @brief The random selector for the position of the return value along the *width* of the OB. + */ + UniformFloatGenerator _xRand; + + /*! + * @brief The random selector for the position of the return value along the *height* of the OB. + */ + UniformFloatGenerator _yRand; + + /*! + * @brief The anchor point of the OB. + */ + Vector2 _minPt; + + /*! + * @brief The cosine of the OB's rotation. + */ + float _cosTheta; + + /*! + * @brief The sine of the OB's rotation. + */ + float _sinTheta; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A weighted integer value. Used with WeightedIntGenerator. + */ + class MENGE_API WeightedInt { + public: + /*! + * @brief Constructor. + * + * @param value The integer value. + * @param weight The relative weight associated with the value. + */ + WeightedInt( int value, float weight): _val(value), _wt( weight ){} + + /*! + * @brief The value of the entry. + */ + int _val; + + /*! + * @brief The weight of the value. + */ + float _wt; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param wInt An instance of the weighted int to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const WeightedInt & wInt ); + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A number generator based on a weighted probability of a discrete value set. + * + * Each value in the set is associated with a weight. The relative probability of any + * given value is that value's weight, divided by the summed weight of all values. + */ + class MENGE_API WeightedIntGenerator : public IntGenerator { + public: + /*! + * @brief Constructor. + */ + WeightedIntGenerator(); + + /*! + * @brief Copy constructor. + * + * The constructed copy should not share the same seed as the original. + * + * @param gen The generator to copy. + */ + WeightedIntGenerator( const WeightedIntGenerator & gen); + + /*! + * @brief Return a value based on the integer generation rules. + * + * @return An integer value drawn from a set with weighted probabilities. + */ + virtual int getValue() const; + + /*! + * @brief Return a value based on the integer generation rules - performed + * in a thread-safe manner. + * + * This is the basic functionality that must be overwridden by derived classes. + * + * @return A integer value. + */ + virtual int getValueConcurrent() const; + + /*! + * @brief Add a value to the set. + * + * @param value The value to add to the set. + * @param weight The weight of the corresponding value. + */ + void addValue( int value, float weight ); + + /*! + * @brief Function for converting the generator to a string on a output stream. + * + * @param out The output stream to write the string representation to. + */ + virtual void print( Logger & out ) const; + + /*! + * @brief Create a copy of itself. + * + * This should only be called after the generator has been finalized. + * Otherwise, the copy will need to be finalized as well. + * + * @returns A pointer to a new generator which is a copy of this one. + * The caller of this function is responsible for freeing up the + * memory for the copy. + */ + virtual IntGenerator * copy() const; + + /*! + * @brief Friend function for writing string representation to an output stream + * + * @param out The output stream. + * @param gen An instance of the generator to represent as a string. + * @returns Reference to the input output stream. + */ + friend Logger & operator<<( Logger & out, const WeightedIntGenerator & gen ); + + /*! + * @brief Finalizes the generator so that it can generate values. + * + * When finished adding points, call this function to post-process them. + * Calling WeightedIntGenerator::getValue before calling this will lead to + * unpredictable results. Furthermore, calling WeightedIntGenerator::addValue + * after calling finalize will likewise lead to unpredictable results. + */ + void finalize(); + protected: + + /*! + * @brief A uniform float generator for "rolling the dice". + */ + UniformFloatGenerator _dice; + + /*! + * @brief The weighted values to select from. + */ + std::vector< WeightedInt > _pairs; + + /*! + * @brief The lock for guaranteeing threadsafe random number generation. + */ + mutable SimpleLock _lock; + }; + + /*! + * @brief Creates a float generator from an xml node. + * + * This function does not maintain responsibility for freeing up the object. + * The calling function is responsible for the memory. + * + * @param node The tiny XML node containing the definition of a scalar float generator. + * @param scale Optional argument for changing the units of the input value. + * (e.g., specification commonly describes angles as degrees, + * but internal representation is in radians). + * @param prefix An optional prefix which may be affixed to the float generator keywords. + * @returns A pointer to a float generator, consistent with the XML definition. + * If there is an error in the definition, NULL is returned. + */ + MENGE_API FloatGenerator * createFloatGenerator( TiXmlElement * node, float scale=1.f, const std::string & prefix="" ); + + /*! + * @brief Creates an int generator from an xml node. + * + * This function does not maintain responsibility for freeing up the object. + * The calling function is responsible for the memory. + * + * @param node The tiny XML node containing the definition of a scalar float generator. + * @param prefix An optional prefix which may be affixed to the float generator keywords. + * @returns A pointer to an int generator, consistent with the XML definition. + * If there is an error in the definition, NULL is returned. + */ + MENGE_API IntGenerator * createIntGenerator( TiXmlElement * node, const std::string & prefix="" ); + + /*! + * @brief Creates a 2D vector generator from an xml node + * + * This function does not maintain responsibility for freeing up the object. + * The calling function is responsible for the memory. + * + * @param node The tiny XML node containing the definition of a vector float generator. + * @param scale Optional argument for changing the units of the input value. + * (e.g., specification commonly describes angles as degrees, + * but internal representation is in radians). + * @returns A pointer to a vector generator, consistent with the XML definition. + * If there is an error in the definition, NULL is returned. + */ + MENGE_API Vec2DGenerator * create2DGenerator( TiXmlElement * node, float scale=1.f ); + + + } // namespace Math +} // namespace Menge +#endif // __RAND_GENERATOR_H__ diff --git a/src/Menge/MengeCore/Math/SimRandom.cpp b/src/Menge/MengeCore/Math/SimRandom.cpp new file mode 100644 index 00000000..9c67e482 --- /dev/null +++ b/src/Menge/MengeCore/Math/SimRandom.cpp @@ -0,0 +1,192 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include +#include +#include + +using namespace std; + +#include "Logger.h" +#include "SimRandom.h" +#include "consts.h" + +namespace Menge { + + namespace Math { + + /* + // Functions r4_normalR and r4_normal_01R are derived from John Burkardt's + // code (with the given licensing information). They have been modified + // to remove the static members so that they could be used in a thread-safe + // re-entrant manner (by placing the burden on the caller to account for + // the fact that the normal generator produces two values at a time. + // + // Modified: 05 October 2013, Sean Curtis + // + // Original credit + // Licensing: + // This code is distributed under the GNU LGPL license. + // + // Modified: + // 29 June 2006 + // + // Author: + // John Burkardt + // + */ + void r4_normalR ( float a, float b, float & val1, float & val2, int *seed ) { + r4_normal_01R( val1, val2, seed ); + + val1 = a + b * val1; + val2 = a + b * val2; + } + + //****************************************************************************80 + + void r4_normal_01R( float & val1, float & val2, int *seed ) { + float r1 = r4_uniform_01( seed ); + + if ( r1 == 0.0 ) { + logger << Logger::ERR_MSG << "\n"; + logger << Logger::ERR_MSG << "R4_NORMAL_01 - Fatal error!\n"; + logger << Logger::ERR_MSG << " R4_UNIFORM_01 returned a value of 0.\n"; + exit ( 1 ); + } + + float r2 = r4_uniform_01 ( seed ); + + val1 = sqrt ( - 2.0f * log ( r1 ) ) * cos ( 2.0f * PI * r2 ); + val2 = sqrt ( - 2.0f * log ( r1 ) ) * sin ( 2.0f * PI * r2 ); + } + + //****************************************************************************80 + + float r4_uniform_01 ( int *seed ) + + //****************************************************************************80 + // + // Purpose: + // + // R4_UNIFORM_01 returns a unit pseudorandom R4. + // + // Discussion: + // + // This routine implements the recursion + // + // seed = 16807 * seed mod ( 2**31 - 1 ) + // r4_uniform_01 = seed / ( 2**31 - 1 ) + // + // The integer arithmetic never requires more than 32 bits, + // including a sign bit. + // + // If the initial seed is 12345, then the first three computations are + // + // Input Output R4_UNIFORM_01 + // SEED SEED + // + // 12345 207482415 0.096616 + // 207482415 1790989824 0.833995 + // 1790989824 2035175616 0.947702 + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Modified: + // + // 16 November 2004 + // + // Author: + // + // John Burkardt + // + // Reference: + // + // Paul Bratley, Bennett Fox, Linus Schrage, + // A Guide to Simulation, + // Springer Verlag, pages 201-202, 1983. + // + // Pierre L'Ecuyer, + // Random Number Generation, + // in Handbook of Simulation + // edited by Jerry Banks, + // Wiley Interscience, page 95, 1998. + // + // Bennett Fox, + // Algorithm 647: + // Implementation and Relative Efficiency of Quasirandom + // Sequence Generators, + // ACM Transactions on Mathematical Software, + // Volume 12, Number 4, pages 362-376, 1986. + // + // Peter Lewis, Allen Goodman, James Miller, + // A Pseudo-Random Number Generator for the System/360, + // IBM Systems Journal, + // Volume 8, pages 136-143, 1969. + // + // Parameters: + // + // Input/output, int *SEED, the "seed" value. Normally, this + // value should not be 0. On output, SEED has been updated. + // + // Output, float R4_UNIFORM_01, a new pseudorandom variate, strictly between + // 0 and 1. + // + { + int k; + float r; + + k = *seed / 127773; + + *seed = 16807 * ( *seed - k * 127773 ) - k * 2836; + + if ( *seed < 0 ) + { + *seed = *seed + 2147483647; + } + // + // Although SEED can be represented exactly as a 32 bit integer, + // it generally cannot be represented exactly as a 32 bit real number! + // + r = ( float ) ( *seed ) * 4.656612875E-10f; + + return r; + } + } // namespace Math +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/SimRandom.h b/src/Menge/MengeCore/Math/SimRandom.h new file mode 100644 index 00000000..1b574c5f --- /dev/null +++ b/src/Menge/MengeCore/Math/SimRandom.h @@ -0,0 +1,89 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimRandom.h + * @brief Functions for calculating normally distributed values. + * + * This code taken from John Burkardt (see normal.cpp). + */ + +#ifndef __SIM_RANDOM_H__ +#define __SIM_RANDOM_H__ + +namespace Menge { + + namespace Math { + /*! + * @brief Generates a quasi-thread-safe, normally distributed random number. + * + * This algorithm generates two normally distributed values at a time. + * To be thread-safe, it could simply dismiss every second value. Alternatively, + * we can provide both values an place the burden on the caller to handle both. + * + * @param a The mean of the probability distribution field (pdf). + * @param b The standard deviation of the pdf. + * @param val1 The first normally distributed value generated. + * @param val2 The second normally distributed value generated. + * @param seed A seed for the random number generator. + * The value in this integer changes with every call. + */ + void r4_normalR ( float a, float b, float & val1, float & val2, int *seed ); + + /*! + * @brief The Box-Muller method for computing two normally distributed + * values at the same time (with mean of 0 and standard deviation of 1. + * + * @param val1 The first normally distributed value generated. + * @param val2 The second normally distributed value generated. + * @param seed A seed for the random number generator. + * @returns The normally distributed number. + */ + void r4_normal_01R ( float & val1, float & val2, int *seed ); + + /*! + * @brief A uniformly generated random number in the range [0, 1] + * + * @param seed A seed for the random number generator. + * @returns The uniformly distributed number. + */ + float r4_uniform_01 ( int *seed ); + + } // namespace Math +} // namespace Menge +#endif //__SIM_RANDOM_H__ diff --git a/src/Menge/MengeCore/Math/Vector2.h b/src/Menge/MengeCore/Math/Vector2.h new file mode 100644 index 00000000..1e6eb79f --- /dev/null +++ b/src/Menge/MengeCore/Math/Vector2.h @@ -0,0 +1,611 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Vector2.h + * @brief Definition of a vector in R2 + */ + +#ifndef __VECTOR2_H__ +#define __VECTOR2_H__ + +#include "CoreConfig.h" +#include +#include +#include "Logger.h" +#include "Math/consts.h" + +#ifdef _MSC_VER + // To export templated classes and functions, requires declaring specializations + // extern. This became standard in C++11, but prior to that it is considered a + // "microsoft extension". This silences the warnings. + #pragma warning( disable : 4231 ) +#endif + +namespace Menge { + + namespace Math { + /*! + * @brief Computes the square of a float. + * @param a The float to be squared. + * @returns The square of the float. + */ + inline MENGE_API float sqr(float a) { + return a * a; + } + + /*! + * @brief Templated vector in R2 + */ + template + class MENGE_API Vector2d { + public: + ///////////////////////////// CONSTRUCTORS //////////////////////////// + /*! + * @brief Default constructor. It does NOT initialize the fields + */ + inline Vector2d() {} + + /*! + * @brief Constructor with arguments + * + * @param x The x-value of the vector. + * @param y The y-value of the vector. + */ + inline Vector2d( Type x, Type y ): _x(x), _y(y) {} + + /*! + * @brief Copy constructor + * + * @param v The vector to copy from. + */ + inline Vector2d( const Vector2d & v ): _x(v._x), _y(v._y) {} + + ///////////////////////////// GETTERS/SETTERS //////////////////////////// + + /*! + * @brief Get the x-value + * + * @returns The x-value of the vector. + */ + inline Type x() const { return _x; } + + /*! + * @brief Get the y-value + * + * @returns The y-value of the vector. + */ + inline Type y() const { return _y; } + + /*! + * @brief Set the x- and y-values from scalar values + * + * @param x The value for the x-component + * @param y The value for the y-component + */ + inline void set( Type x, Type y ) { + _x = x; + _y = y; + } + + /*! + * @brief Set the x- and y-values from a vector + * + * @param v The vector containing the x- and y-values + */ + inline void set( const Vector2d & v ) { + _x = v._x; + _y = v._y; + } + + /*! + * @brief Set the x-value + * + * @param x The x-value. + */ + inline void setX( Type x ) { + _x = x; + } + + /*! + * @brief Set the y-value + * + * @param y The y-value. + */ + inline void setY( Type y ) { + _y = y; + } + + /*! + * @brief Set the vector to zero + */ + inline void zero() { + _x = _y = (Type)0; + } + + ///////////////////////////// MATH OPERATIONS //////////////////////////// + + /*! + * @brief Vector negation. Creates a new vector which is the + * negation of this vector + * + * @returns The vector in the opposite direction of this vector + */ + inline Vector2d operator-() const { + return Vector2d( -_x, -_y ); + } + + /*! + * @brief Computes the dot product of this vector with the + * given vector. + * + * @param v The two-dimensional vector with which the + * dot product should be computed. + * @returns The dot product of this two-dimensional vector with the + * specified two-dimensional vector. + */ + inline float operator*(const Vector2d& v) const { + return _x * v._x + _y * v._y; + } + + /*! + * @brief Computes the scalar multiplication of this + * vector with the given scalar value. + * + * @param s The scalar value + * @returns The scalar multiplication of this vector + * with the specified scalar value. + */ + inline Vector2d operator*( float s ) const { + return Vector2d( _x * s, _y * s ); + } + + /*! + * @brief Computes the scalar division of this + * vector with the given scalar value. + * + * @param s The scalar value + * @returns The scalar division of this vector + * with the specified scalar value. + */ + inline Vector2d operator/( float s ) const { + const float invS = 1.f / s; + return Vector2d( _x * invS, _y * invS ); + } + + /*! + * @brief Computes the vector sum of this vector with + * the given vector. + * + * @param v The second operand. + * @returns The vector sum of this vector with the + * given vector. + */ + inline Vector2d operator+( const Vector2d & v ) const { + return Vector2d( _x + v._x, _y + v._y ); + } + + /*! + * @brief Computes the vector difference of this vector with + * the given vector. + * + * @param v The second operand. + * @returns The vector difference of this vector with the + * given vector. + */ + inline Vector2d operator-( const Vector2d & v ) const { + return Vector2d( _x - v._x, _y - v._y ); + } + + /*! + * @brief Reports if this vector is the same as the given + * vector. + * + * @param v The second operand. + * @returns True if the vectors are exactly identical, False + * otherwise + */ + inline bool operator==( const Vector2d & v ) const { + return _x == v._x && _y == v._y; + } + + /*! + * @brief Reports if this vector is the different from the given + * vector. + * + * @param v The second operand. + * @returns True if the vectors are at all different, + * false otherwise + */ + inline bool operator!=( const Vector2d & v ) const { + return _x != v._x || _y != v._y; + } + + ///////////////////////////// IN-PLACE MATH OPERATIONS //////////////////////////// + + /*! + * @brief Perform in-place scalar multiplication on this vector. + * + * @param s The scalar mutliplicand. + * @return A reference to the vector. + */ + inline Vector2d & operator*=( float s ) { + _x *= s; + _y *= s; + return *this; + } + + /*! + * @brief Perform in-place scalar division on this vector. + * + * @param s The scalar divisor. + * @return A reference to the vector. + */ + inline Vector2d & operator/=( float s ) { + const float invS = 1.f / s; + _x *= invS; + _y *= invS; + return *this; + } + + /*! + * @brief Perform in-place vector addition on this vector. + * + * @param v The second vector operand. + * @return A reference to the vector. + */ + inline Vector2d & operator+=( const Vector2d & v ) { + _x += v._x; + _y += v._y; + return *this; + } + + /*! + * @brief Perform in-place vector subtraction on this vector. + * + * @param v The second vector operand. + * @return A reference to the vector. + */ + inline Vector2d & operator-=( const Vector2d & v ) { + _x -= v._x; + _y -= v._y; + return *this; + } + + /*! + * @brief Negate the vector in place + */ + inline void negate() { + _x = -_x; + _y = -_y; + } + + /*! + * @brief Normalize the vector in place + */ + inline void normalize() { + float len = sqrtf( _x * _x + _y * _y ); + if ( len > EPS ) { + _x /= len; + _y /= len; + } else { + _x = _y = 0.f; + } + } + + ///////////////////////////// GEOMETRIC OPERATIONS //////////////////////////// + + /*! + * @brief Compute the magnitude (aka length) of the vector + * + * @returns The magnitude of the vector. + */ + inline Type Length() const { + return sqrt( _x * _x + _y * _y ); + } + + /*! + * @brief Compute the distance from this vector to another point + * + * @param p The point whose distance from this vector + * (interpreted as a point) is to be computed + * @returns The distance between this vector and p. + */ + inline float distance( const Vector2d & p ) const { + float dx = _x - p._x; + float dy = _y - p._y; + return sqrtf( dx * dx + dy * dy ); + } + + /*! + * @brief Compute the distance from this vector to another point + * + * @param x The x-value of the other point. + * @param y The y-value of the other point. + * @returns The distance between this vector and (x, y). + */ + inline float distance( float x, float y ) const { + float dx = _x - x; + float dy = _y - y; + return sqrtf( dx * dx + dy * dy ); + } + + /*! + * @brief Compute the squared-distance from this vector to another point + * + * @param p The point whose distance from this vector + * (interpreted as a point) is to be computed + * @returns The squared-distance between this vector and p. + */ + inline float distanceSq( const Vector2d & p ) const { + float dx = _x - p._x; + float dy = _y - p._y; + return dx * dx + dy * dy ; + } + + /*! + * @brief Compute the squared-distance from this vector to another point + * + * @param x The x-value of the other point. + * @param y The y-value of the other point. + * @returns The squared-distance between this vector and (x, y). + */ + inline float distanceSq( float x, float y ) const { + float dx = _x - x; + float dy = _y - y; + return dx * dx + dy * dy; + } + + /*! + * @brief x-component of the vector + */ + Type _x; + + /*! + * @brief y-component of the vector + */ + Type _y; + }; + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template class MENGE_API Vector2d; + + /*! + * @brief Declaration of a floating point vector in R2. + */ + typedef Vector2d Vector2; + + ///////////////////////////// UTILITY FUNCTIONS //////////////////////////// + + + /*! + * @brief Computes the left scalar multiplication of a scalar and 2d vector. + * + * @param s The scalar value with which the scalar + * multiplication should be computed. + * @param v The two-dimensional vector with which the scalar + * multiplication should be computed. + * @returns The scalar multiplication of the two-dimensional vector with the + * scalar value. + */ + template< class Type > + inline MENGE_API Vector2d operator*( Type s, const Vector2d& v) { + return Vector2d( s * v._x, s * v._y ); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Vector2d operator*( float s, const Vector2d& v); + + /*! + * @brief Inserts the specified two-dimensional vector into the logger. + * + * @param logger The logger into which the two-dimensional + * vector should be inserted. + * @param v The two-dimensional vector which to insert into + * the output stream. + * @returns A reference to the output stream. + */ + template< class Type > + inline MENGE_API Logger& operator<<(Logger& logger, const Vector2d& v ) { + logger << "(" << v.x() << "," << v.y() << ")"; + return logger; + } + + /*! + * @brief Inserts the specified two-dimensional vector into the specified + * output stream. + * + * @param os The output stream into which the two-dimensional + * vector should be inserted. + * @param v The two-dimensional vector which to insert into + * the output stream. + * @returns A reference to the output stream. + */ + template< class Type > + inline MENGE_API std::ostream& operator<<(std::ostream& os, const Vector2d& v ) { + os << "(" << v.x() << "," << v.y() << ")"; + return os; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Logger& operator<<(Logger& os, const Vector2d& v ); + + /*! + * @brief Computes the length of a specified two-dimensional vector. + * + * @param v The two-dimensional vector whose length is to be + * computed. + * @returns The length of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Type abs( const Vector2d& v ) { + return std::sqrt( v * v ); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float abs( const Vector2d& v ); + + /*! + * @brief Computes the squared length of a specified two-dimensional + * vector. + * + * @param v The two-dimensional vector whose squared length + * is to be computed. + * @returns The squared length of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Type absSq( const Vector2d& v ) { + return v * v; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float absSq( const Vector2d& v ); + + /*! + * @brief Computes the determinant of a two-dimensional square matrix with + * rows consisting of the specified two-dimensional vectors. + * + * @param v1 The top row of the two-dimensional square + * matrix. + * @param v2 The bottom row of the two-dimensional square + * matrix. + * @returns The determinant of the two-dimensional square matrix. + */ + template< class Type > + inline MENGE_API Type det( const Vector2d& v1, const Vector2d& v2) { + return v1.x() * v2.y() - v1.y() * v2.x(); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float det( const Vector2d& v1, const Vector2d& v2); + + /*! + * @brief Computes the normalization of the specified two-dimensional + * vector. + * + * @param vector The two-dimensional vector whose normalization + * is to be computed. + * @returns The normalization of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Vector2d norm(const Vector2d& vector) { + float mag = abs( vector ); + if ( mag < EPS ) { + // This may not be the "right" behavior. I do this because the "normalized" vector has unit + // length. This guarantees that the result is always unit length. Although it introduces other + // issues. + return Vector2d(1.f, 0.f); + } else { + return vector / mag; + } + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Vector2d norm(const Vector2d& vector); + + /*! + * @brief Determines if two vectors are equal to within a threshhold + * + * @param v1 The first of two-dimensional vectors to be compared + * @param v2 The second of two-dimensional vectors to be compared + * @param threshSqd The squared threshhold to test against + * defaults to 3 decimal places (0.001)^2 + * @returns A boolean: true if they are equivalent within a threshhold, + * false otherwise. + */ + template< class Type > + inline MENGE_API bool equivalent( const Vector2d & v1, const Vector2d & v2, float threshSqd=0.000001f ) { + return absSq( v1 - v2 ) < threshSqd; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API bool equivalent( const Vector2d & v1, const Vector2d & v2, float threshSqd ); + + /*! + * @brief Computes the signed distance from a line connecting the + * specified points to a specified point. + * @param a The first point on the line. + * @param b The second point on the line. + * @param c The point to which the signed distance is to + * be calculated. + * @returns Positive when the point c lies to the left of the line ab. + */ + template< class Type > + inline MENGE_API Type leftOf(const Vector2d& a, const Vector2d& b, const Vector2d& c) { + return det(a - c, b - a); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float leftOf(const Vector2d& a, const Vector2d& b, const Vector2d& c); + } // namespace Math +} // namespace Menge + + #ifdef _MSC_VER + // To export templated classes and functions, requires declaring specializations + // extern. This became standard in C++11, but prior to that it is considered a + // "microsoft extension". This silences the warnings. + #pragma warning( default : 4231 ) + #endif +#endif //__VECTOR2_H__ diff --git a/src/Menge/MengeCore/Math/Vector3.h b/src/Menge/MengeCore/Math/Vector3.h new file mode 100644 index 00000000..7fa4fd6a --- /dev/null +++ b/src/Menge/MengeCore/Math/Vector3.h @@ -0,0 +1,762 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Vector3.h + * @brief Definition of a vector in R3 + */ + +#ifndef __VECTOR3_H__ +#define __VECTOR3_H__ + +#ifdef _MSC_VER + // To export templated classes and functions, requires declaring specializations + // extern. This became standard in C++11, but prior to that it is considered a + // "microsoft extension". This silences the warnings. + #pragma warning( disable : 4231 ) +#endif + +#include "CoreConfig.h" +#include "Logger.h" +#include "Math/consts.h" +#include +#include +#include + +namespace Menge { + + namespace Math { + + // forward declaration + template< class Type > + class Vector3d; + + template< class Type > + inline MENGE_API Type abs( const Vector3d& v ); + + /*! + * @brief Templated vector in R3 + */ + template + class MENGE_API Vector3d { + + public: + ///////////////////////////// CONSTRUCTORS //////////////////////////// + /*! + * @brief Default constructor. It does NOT initialize the fields + */ + inline Vector3d() {} + + /*! + * @brief Constructor with arguments + * + * @param x The vector's x-component. + * @param y The vector's y-component. + * @param z The vector's z-component. + */ + inline Vector3d( Type x, Type y, Type z ): _x(x), _y(y), _z(z) {} + + /*! + * @brief Copy constructor + * + * @param v The vector to copy from. + */ + inline Vector3d( const Vector3d & v ): _x(v._x), _y(v._y), _z(v._z) {} + + ///////////////////////////// GETTERS/SETTERS //////////////////////////// + + /*! + * @brief Get the x-value + * + * @returns The x-value. + */ + inline Type x() const { return _x; } + + /*! + * @brief Get the y-value + * + * @returns The y-value. + */ + inline Type y() const { return _y; } + + /*! + * @brief Get the z-value + * + * @returns The z-value. + */ + inline Type z() const { return _z; } + + /*! + * @brief Set the x- and y-values from scalar values + * + * @param x The value for the x-component + * @param y The value for the y-component + * @param z The value for the z-component + */ + inline void set( Type x, Type y, Type z ) { + _x = x; + _y = y; + _z = z; + } + + /*! + * @brief Set the x-, y- and z-values from a vector + * + * @param v The vector containing the newvalues + */ + inline void set( const Vector3d & v ) { + _x = v._x; + _y = v._y; + _z = v._z; + } + + /*! + * @brief Set the x-value + * + * @param x The x-value. + */ + inline void setX( Type x ) { + _x = x; + } + + /*! + * @brief Set the y-value + * + * @param y The y-value. + */ + inline void setY( Type y ) { + _y = y; + } + + /*! + * @brief Set the z-value + * + * @param z The z-value. + */ + inline void setZ( Type z ) { + _z = z; + } + + /*! + * @brief Index-style access to vector components + * + * @param i The index of the desired component. + * Sould be in the range [0, 2]. + * @returns The ith component of the vector. + */ + inline Type operator[]( const int i ) const { + assert( i >= 0 && i <= 2 && "Invalid index for Vector3" ); + return i == 0 ? _x : ( i == 1 ? _y : _z ); + } + + /*! + * @brief Index-style access to vector components as a reference + * + * @param i The index of the desired component. + * Sould be in the range [0, 2]. + * @returns A reference to the ith component of the vector. + */ + inline Type & operator[]( const int i ) { + assert( i >= 0 && i <= 2 && "Invalid index for Vector3" ); + return i == 0 ? _x : ( i == 1 ? _y : _z ); + } + + /*! + * @brief Set the vector to zero + */ + inline void zero() { + _x = _y = _z = (Type)0; + } + + ///////////////////////////// MATH OPERATIONS //////////////////////////// + + /*! + * @brief Vector negation. Creates a new vector which is the + * negation of this vector + * + * @returns The vector in the opposite direction of this vector + */ + inline Vector3d operator-() const { + return Vector3d( -_x, -_y, -_z ); + } + + /*! + * @brief Computes the dot product of this vector with the + * given vector. + * + * @param v The with which the + * dot product should be computed. + * @returns The dot product of this vector with the given vector + */ + inline float operator*(const Vector3d& v) const { + return _x * v._x + _y * v._y + _z * v._z; + } + + /*! + * @brief Computes the scalar multiplication of this + * vector with the given scalar value. + * + * @param s The scalar value + * @returns The scalar multiplication of this vector + * with a specified scalar value. + */ + inline Vector3d operator*( float s ) const { + return Vector3d( _x * s, _y * s, _z * s ); + } + + /*! + * @brief Computes the scalar division of this + * vector with the given scalar value. + * + * @param s The scalar value + * @returns The scalar division of this vector + * with a specified scalar value. + */ + inline Vector3d operator/( float s ) const { + const float invS = 1.f / s; + return Vector3d( _x * invS, _y * invS, _z * invS ); + } + + /*! + * @brief Computes the vector sum of this vector with + * the given vector. + * + * @param v The second operand. + * @returns The vector sum of this vector with the + * given vector. + */ + inline Vector3d operator+( const Vector3d & v ) const { + return Vector3d( _x + v._x, _y + v._y, _z + v._z ); + } + + /*! + * @brief Computes the vector difference of this vector with + * the given vector. + * + * @param v The second operand. + * @returns The vector difference of this vector with the + * given vector. + */ + inline Vector3d operator-( const Vector3d & v ) const { + return Vector3d( _x - v._x, _y - v._y, _z - v._z ); + } + + /*! + * @brief Reports if this vector is the same as the given + * vector. + * + * @param v The second operand. + * @returns True if the vectors are exactly identical, False + * otherwise + */ + inline bool operator==( const Vector3d & v ) const { + return _x == v._x && _y == v._y && _z == v._z; + } + + /*! + * @brief Reports if this vector is the different from the given + * vector. + * + * @param v The second operand. + * @returns True if the vectors are at all different, + * false otherwise + */ + inline bool operator!=( const Vector3d & v ) const { + return _x != v._x || _y != v._y || _z != v._z; + } + + ///////////////////////////// IN-PLACE MATH OPERATIONS //////////////////////////// + + /*! + * @brief Perform in-place scalar multiplication on this vector. + * + * @param s The scalar mutliplicand. + * @return A reference to the vector. + */ + inline Vector3d & operator*=( float s ) { + _x *= s; + _y *= s; + _z *= s; + return *this; + } + + /*! + * @brief Perform in-place scalar division on this vector. + * + * @param s The scalar divisor. + * @return A reference to the vector. + */ + inline Vector3d & operator/=( float s ) { + const float invS = 1.f / s; + _x *= invS; + _y *= invS; + _z *= invS; + return *this; + } + + /*! + * @brief Perform in-place vector addition on this vector. + * + * @param v The second vector operand. + * @return A reference to the vector. + */ + inline Vector3d & operator+=( const Vector3d & v ) { + _x += v._x; + _y += v._y; + _z += v._z; + return *this; + } + + /*! + * @brief Perform in-place vector subtraction on this vector. + * + * @param v The second vector operand. + * @return A reference to the vector. + */ + inline Vector3d & operator-=( const Vector3d & v ) { + _x -= v._x; + _y -= v._y; + _z -= v._z; + return *this; + } + + /*! + * @brief Negate the vector in place + */ + inline void negate() { + _x = -_x; + _y = -_y; + _z = -_z; + } + + /*! + * @brief Normalize the vector in place + */ + inline void normalize() { + float len = sqrtf( _x * _x + _y * _y + _z * _z ); + if ( len > EPS ) { + _x /= len; + _y /= len; + _z /= len; + } else { + _x = _y = _z = 0.f; + } + } + + /*! + * @brief Adds in a scaled version of another vector + * this += s * v + * + * @param s The scale factor for the vector v + * @param v The vector to scale + */ + inline void SumScale( Type s, const Vector3d & v ) { + _x += v._x * s; + _y += v._y * s; + _z += v._z * s; + } + + ///////////////////////////// ROTATION OPERATIONS //////////////////////////// + + /*! + * @brief Rotate the vector around the x axis + * + * @param angle The amoutn of rotations (in radians) + * @returns The rotated vector + */ + Vector3d rotateX( float angle ) const { + float newY = _y, newZ = _z; + rotatePair( angle, &newY, &newZ ); + return Vector3d( _x, newY, newZ ); + } + + /*! + * @brief Rotate the vector around the y axis + * + * @param angle The amoutn of rotations (in radians) + * @returns The rotated vector + */ + Vector3d rotateY( float angle ) const { + float newX = _x, newZ = _z; + rotatePair( angle, &newX, &newZ ); + return Vector3d( newX, _y, newZ ); + } + + /*! + * @brief Rotate the vector around the z axis + * + * @param angle The amoutn of rotations (in radians) + * @returns The rotated vector + */ + Vector3d rotateZ( float angle ) const { + float newX = _x, newY = _y; + rotatePair( -angle, &newX, &newY ); + return Vector3d( newX, newY, _z ); + } + + /*! + * @brief Rotate the vector around an arbitrary vector + * + * @param angle The amoutn of rotations (in radians) + * @param v The axis of rotation - it should be normalized + * @returns The rotated vector + */ + Vector3d rotateV( Type angle, const Vector3d & v ) const { + assert ( abs( v ) > 0.999 && abs( v ) < 1.001 ); + Type c = cos( angle ); + Type s = sin( angle ); + Type omc = 1 - c; + // This is a hack -- it should be done with a matrix..... + Type vx = _x * (v._x * v._x * omc + c) + _y * (v._y * v._x * omc + v._z * s) + _z * (v._z * v._x * omc - v._y * s); + Type vy = _x * (v._x * v._y * omc - v._z * s) + _y * (v._y * v._y * omc + c) + _z * (v._z * v._y * omc + v._x * s); + Type vz = _x * (v._x * v._z * omc + v._y * s) + _y * (v._y * v._z * omc - v._x * s) + _z * (v._z * v._z * omc + c); + return Vector3d( vx, vy, vz ); + } + + /*! + * @brief Rotate the vector around an arbitrary vector - change the vector in place + * + * @param angle The amoutn of rotations (in radians) + * @param v The axis of rotation - it should be normalized + */ + void rotateV_ip( Type angle, const Vector3d & v ) { + assert ( abs( v ) > 0.999 && abs( v ) < 1.001 ); + Type c = cos( angle ); + Type s = sin(angle); + Type omc = 1 - c; + // This is a hack -- it should be done with a matrix..... + Type vx = _x * (v._x * v._x * omc + c) + _y * (v._y * v._x * omc + v._z * s) + _z * (v._z * v._x * omc - v._y * s); + Type vy = _x * (v._x * v._y * omc - v._z * s) + _y * (v._y * v._y * omc + c) + _z * (v._z * v._y * omc + v._x * s); + Type vz = _x * (v._x * v._z * omc + v._y * s) + _y * (v._y * v._z * omc - v._x * s) + _z * (v._z * v._z * omc + c); + _x = vx; + _y = vy; + _z = vz; + } + + ///////////////////////////// GEOMETRIC OPERATIONS //////////////////////////// + + /*! + * @brief Compute the magnitude (aka length) of the vector + * + * @returns The magnitude of the vector. + */ + inline Type Length() const { + return sqrt( _x * _x + _y * _y + _z * _z ); + } + + /*! + * @brief Cross product of this vector with the given vector + * this x v + * + * @param v The second opearand. + * @returns The vector representing the cross product of this with v. + */ + inline Vector3d cross( const Vector3d & v ) { + return Vector3d( _y * v._z - v._y * _z, + _z * v._x - _x * v._z, + _x * v._y - _y * v._x); + } + + /*! + * @brief Compute the distance from this vector to another point + * + * @param p The point whose distance from this vector + * (interpreted as a point) is to be computed + * @returns The distance between this vector and p. + */ + inline float distance( const Vector3d & p ) const { + float dx = _x - p._x; + float dy = _y - p._y; + float dz = _z - p._z; + return sqrtf( dx * dx + dy * dy + dz * dz ); + } + + /*! + * @brief Compute the distance from this vector to another point + * + * @param x The x-value of the other point. + * @param y The y-value of the other point. + * @param z The z-value of the other point. + * @returns The distance between this vector and (x, y). + */ + inline float distance( float x, float y, float z ) const { + float dx = _x - x; + float dy = _y - y; + float dz = _z - z; + return sqrtf( dx * dx + dy * dy + dz * dz ); + } + + /*! + * @brief Compute the squared-distance from this vector to another point + * + * @param p The point whose distance from this vector + * (interpreted as a point) is to be computed + * @returns The squared-distance between this vector and p. + */ + inline float distanceSq( const Vector3d & p ) const { + float dx = _x - p._x; + float dy = _y - p._y; + float dz = _z - p._z; + return dx * dx + dy * dy + dz * dz ; + } + + /*! + * @brief Compute the squared-distance from this vector to another point + * + * @param x The x-value of the other point. + * @param y The y-value of the other point. + * @param z The z-value of the other point. + * @returns The squared-distance between this vector and (x, y). + */ + inline float distanceSq( float x, float y, float z ) const { + float dx = _x - x; + float dy = _y - y; + float dz = _z - z; + return dx * dx + dy * dy + dz * dz; + } + + /*! + * @brief x-component of the vector + */ + Type _x; + + /*! + * @brief y-component of the vector + */ + Type _y; + + /*! + * @brief z-component of the vector + */ + Type _z; + + private: + /*! + * @brief Rotate a 2D vector. + * + * @param angle The amount of rotation (in radians). + * @param x The x-component of the vector. + * @param y The y-component of the vector. + */ + void rotatePair( float angle, float * x, float * y ) const { + float c = cos( angle ); + float s = sin( angle ); + float newX = c * (*x) + s * (*y); + float newY = c * (*y) - s * (*x); + *x = newX; + *y = newY; + } + }; + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template class MENGE_API Vector3d; + + /*! + * @brief Declaration of a floating point vector in R3. + */ + typedef Vector3d Vector3; + + ///////////////////////////// UTILITY FUNCTIONS //////////////////////////// + + + /*! + * @brief Computes the left scalar multiplication of a scalar and 2d vector. + * + * @param s The scalar value with which the scalar + * multiplication should be computed. + * @param v The two-dimensional vector with which the scalar + * multiplication should be computed. + * @returns The scalar multiplication of the two-dimensional vector with the + * scalar value. + */ + template< class Type > + inline MENGE_API Vector3d operator*( Type s, const Vector3d& v) { + return Vector3d( s * v._x, s * v._y, s * v._z ); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Vector3d operator*( float s, const Vector3d& v); + + /*! + * @brief Inserts the specified two-dimensional vector into the logger. + * + * @param logger The logger into which the two-dimensional + * vector should be inserted. + * @param v The two-dimensional vector which to insert into + * the output stream. + * @returns A reference to the output stream. + */ + template< class Type > + inline MENGE_API Logger& operator<<(Logger& logger, const Vector3d& v ) { + logger << "(" << v.x() << "," << v.y() << ", " << v.z() << ")"; + return logger; + } + + /*! + * @brief Inserts the specified two-dimensional vector into the specified + * output stream. + * + * @param os The output stream into which the two-dimensional + * vector should be inserted. + * @param v The two-dimensional vector which to insert into + * the output stream. + * @returns A reference to the output stream. + */ + template< class Type > + inline MENGE_API std::ostream& operator<<(std::ostream& os, const Vector3d& v ) { + os << "(" << v.x() << "," << v.y() << ", " << v.z() << ")"; + return os; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Logger& operator<<(Logger& os, const Vector3d& v ); + + /*! + * @brief Computes the length of a specified two-dimensional vector. + * + * @param v The two-dimensional vector whose length is to be + * computed. + * @returns The length of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Type abs( const Vector3d& v ) { + return std::sqrt( v * v ); + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float abs( const Vector3d& v ); + + /*! + * @brief Computes the squared length of a specified two-dimensional + * vector. + * + * @param v The two-dimensional vector whose squared length + * is to be computed. + * @returns The squared length of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Type absSq( const Vector3d& v ) { + return v * v; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API float absSq( const Vector3d& v ); + + /*! + * @brief Computes the normalization of the specified two-dimensional + * vector. + * + * @param vector The two-dimensional vector whose normalization + * is to be computed. + * @returns The normalization of the two-dimensional vector. + */ + template< class Type > + inline MENGE_API Vector3d norm( const Vector3d& vector ) { + Type mag = abs( vector ); + if ( mag < EPS ) { + // This may not be the "right" behavior. I do this because the "normalized" vector has unit + // length. This guarantees that the result is always unit length. Although it introduces other + // issues. + return Vector3d( 1.f, 0.f, 0.f ); + } else { + return vector / mag; + } + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API Vector3d norm( const Vector3d& vector ); + + /*! + * @brief Determines if two vectors are equal to within a threshhold + * + * @param v1 The first of two-dimensional vectors to be compared + * @param v2 The second of two-dimensional vectors to be compared + * @param threshSqd The squared threshhold to test against + * defaults to 3 decimal places (0.001)^2 + * @returns A boolean: true if they are equivalent within a threshhold, + * false otherwise. + */ + template< class Type > + inline MENGE_API bool equivalent( const Vector3d & v1, const Vector3d & v2, float threshSqd=0.000001f ) { + return absSq( v1 - v2 ) < threshSqd; + } + + /*! + * @brief Explicit specialization for shared library export. + * @internal + */ + MATHEXTERN template MENGE_API bool equivalent( const Vector3d & v1, const Vector3d & v2, float threshSqd ); + + // Possible operations + // Normal to a trio of points (i.e. normal of triangle) + // Optimized math operations + // add in scaled vector + // scale this add in scaled vector + // Getter/setter from Type pointer + // Linear interpolation + // reflection of one vector around another + // Compute plane from three points + + } // namespace Math +} // namespace Menge +#ifdef _MSC_VER + // To export templated classes and functions, requires declaring specializations + // extern. This became standard in C++11, but prior to that it is considered a + // "microsoft extension". This silences the warnings. + #pragma warning( default : 4231 ) +#endif + +#endif diff --git a/src/Menge/MengeCore/Math/consts.h b/src/Menge/MengeCore/Math/consts.h new file mode 100644 index 00000000..41845fc2 --- /dev/null +++ b/src/Menge/MengeCore/Math/consts.h @@ -0,0 +1,88 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file consts.h + * @brief Some common mathematical constants. + */ + +#ifndef __CONSTS_H__ +#define __CONSTS_H__ + +#include "CoreConfig.h" +#include + +namespace Menge { + + /*! + * @brief A convenient definition of infinity. + */ + extern MENGE_API const float INFTY; + + /*! + * @brief pi. + */ + extern MENGE_API const float PI; + + /*! + * @brief 2 * pi. + */ + extern MENGE_API const float TWOPI; + + /*! + * @brief pi / 2. + */ + extern MENGE_API const float HALFPI; + /*! + * @brief Scale factor for converting degrees to radians. + */ + extern MENGE_API const float DEG_TO_RAD; + + /*! + * @brief Scale factor for converting radians to degrees. + */ + extern MENGE_API const float RAD_TO_DEG; + + /*! + * @brief Suitably small number for testing for functional zero values. + */ + extern MENGE_API const float EPS; + +} // namespace Menge + +#endif // __CONSTS_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/geomQuery.cpp b/src/Menge/MengeCore/Math/geomQuery.cpp new file mode 100644 index 00000000..8853bfc2 --- /dev/null +++ b/src/Menge/MengeCore/Math/geomQuery.cpp @@ -0,0 +1,91 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "geomQuery.h" +#include "consts.h" + +namespace Menge { + + //////////////////////////////////////////////////////////////// + + const float INFTY = 1e6f; + const float PI = (float)(asin( 1.0f ) * 2.f); + const float TWOPI = PI * 2.f; + const float HALFPI = PI * 0.5f; + const float DEG_TO_RAD = PI / 180.0f; + const float RAD_TO_DEG = 180.0f / PI; + const float EPS = 0.00001f; + + namespace Math { + + //////////////////////////////////////////////////////////////// + + // determines the time to collision of a ray from the origin with a circle (center, radius) + // Returns an "infinity" style number if no collision + float rayCircleTTC( const Vector2 & dir, const Vector2 & center, float radius ) { + float a = absSq( dir ); + float b = -2 * ( dir * center ); + float c = absSq( center ) - ( radius * radius ); + float discr = b * b - 4 * a * c; + if ( discr < 0.f ) { + return INFTY; + } + const float sqrtDiscr = sqrtf( discr ); + float t0 = ( -b - sqrtDiscr ) / ( 2.f * a ); + float t1 = ( -b + sqrtDiscr ) / ( 2.f * a ); + // If the points of collision have different signs, it means I'm already colliding + if (( t0 < 0.f && t1 > 0.f ) || + ( t1 < 0.f && t0 > 0.f ) ) return 0.f; + if ( t0 < t1 && t0 > 0.f ) return t0; + else if ( t1 > 0.f ) return t1; + else return INFTY; + } + + //////////////////////////////////////////////////////////////// + + // Computes the spherical linear interpolation between two vectors + // the result is (conceptually) (1-t)*p0 + t*p1 + // sinTheta is the sine of the angle between p1 and p1 + Vector2 slerp( float t, const Vector2 & p0, const Vector2 & p1, float sinTheta ) { + float theta = asin( sinTheta ); + float t0 = sin( (1 - t ) * theta ) / sinTheta; + float t1 = sin( t * theta ) / sinTheta; + return p0 * t0 + p1 * t1; + } + } // namespace Math +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Math/geomQuery.h b/src/Menge/MengeCore/Math/geomQuery.h new file mode 100644 index 00000000..c8e1fe80 --- /dev/null +++ b/src/Menge/MengeCore/Math/geomQuery.h @@ -0,0 +1,84 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file geomQuery.h + * @brief Various mathematical operations and queries on geometry + */ + +#ifndef __GEOM_QUERY_H__ +#define __GEOM_QUERY_H__ + +#include "CoreConfig.h" +#include "Vector2.h" + +namespace Menge { + + /*! + * @namespace Math + * @brief The namespace for math primitives for simulation and visualization. + */ + namespace Math { + /*! + * @brief Computes the time to collision between a ray and a circle + * + * This is a special-case test. It assumes the ray originates + * from the origin of the world. + * + * @param dir A vector in R2 describing the direction (from the origin) + * of the ray. (Does not need to be normalized) + * @param center A vector in R2 describing the position of the circle center. + * @param radius A float. The radius of the circle. + * @returns The expected "time" to collision ("infinity" if there is no collision). + */ + MENGE_API float rayCircleTTC( const Vector2 & dir, const Vector2 & center, float radius ); + + /*! + * @brief Perform spherical linear interpolation between two vectors + * + * @param t The blend parameter. T lies in the interval [0, 1] + * @param p0 The first vector to interpolate (assumes ||p0|| = 1.0. + * @param p1 The first vector to interpolate (assumes ||p1|| = 1.0. + * @param sinTheta The sine of the angle between the two vectors. + * @returns The interpolated vector. + */ + MENGE_API Vector2 slerp( float t, const Vector2 & p0, const Vector2 & p1, float sinTheta ); + } // namespace Math + +} // namespace Menge +#endif // __GEOM_QUERY_H__ diff --git a/src/Menge/MengeCore/Math/vector.h b/src/Menge/MengeCore/Math/vector.h new file mode 100644 index 00000000..4b00f274 --- /dev/null +++ b/src/Menge/MengeCore/Math/vector.h @@ -0,0 +1,56 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file vector.h + * @brief Collection of Vector2, Vector3, and constants for simple inclusion. + */ + + +#ifndef VECTOR_H + +#define VECTOR_H +#include + +#include +#include +#include "consts.h" +#include "Vector2.h" +#include "Vector3.h" + +#endif diff --git a/src/Menge/MengeCore/MengeException.h b/src/Menge/MengeCore/MengeException.h new file mode 100644 index 00000000..ce55b3f0 --- /dev/null +++ b/src/Menge/MengeCore/MengeException.h @@ -0,0 +1,116 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file MengeException.h + * @brief The base definition for exceptions in Menge. + * + * TODO: Refactor all exceptions to inherit from this class. + */ + +#ifndef __MENGE_EXCEPTION_H__ +#define __MENGE_EXCEPTION_H__ + +#include "CoreConfig.h" +#include +#include + +namespace Menge { + + /*! + * @brief Base exception class for menge operations. + */ + class MENGE_API MengeException : public std::exception { + public: + + /*! + * @brief Default constructor. + */ + MengeException() : std::exception() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + MengeException( const std::string & s ):std::exception(), _msg(s) {} + + /*! + * @brief Destructor. + */ + ~MengeException() throw(){} + + /*! + * @brief Provides the exception message. + * + * @returns A pointer to the exception message. + */ + virtual const char * what() const throw() { + return _msg.c_str(); + } + + /*! + * @brief The exception message. + */ + std::string _msg; + }; + + /*! + * @brief Base class for *fatal* exceptions. + * + * A fatal exception is one that requires the simulator to stop because + * it has achieved an inoperable state. + */ + class MENGE_API MengeFatalException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + MengeFatalException(): MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + MengeFatalException( const std::string & s ):MengeException(s) {} + }; + +} // namespace Menge + +#endif // __MENGE_EXCEPTION_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Orca/ORCA.h b/src/Menge/MengeCore/Orca/ORCA.h new file mode 100644 index 00000000..fc10656f --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCA.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCA.h + * @brief Collection of ORCA Agent and Simulator for simple inclusion. + */ + +#ifndef __ORCA_H__ +#define __ORCA_H__ + +#include "ORCASimulator.h" +#include "ORCAAgent.h" + +#endif diff --git a/src/Menge/MengeCore/Orca/ORCAAgent.cpp b/src/Menge/MengeCore/Orca/ORCAAgent.cpp new file mode 100644 index 00000000..fbe7a748 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCAAgent.cpp @@ -0,0 +1,538 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include +#include + +#include "ORCAAgent.h" +#include "ORCASimulator.h" +#include "Math/consts.h" + +namespace ORCA { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of ORCA::Agent + ///////////////////////////////////////////////////////////////////////////// + + // AGENT DEFAULT PARAMETERS + const float Agent::TAU = 2.5f; ///< The default value for tau (the time horizon w.r.t. other agents). + const float Agent::TAU_OBST = 0.15f; ///< The default value for tau obstacles (the time horizon w.r.t. obstacles). + + ///////////////////////////////////////////////////////////////////////////// + + Agent::Agent(): Menge::Agents::BaseAgent() { + _timeHorizon = TAU; + _timeHorizonObst = TAU_OBST; + } + + ///////////////////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + ///////////////////////////////////////////////////////////////////////////// + + void Agent::obstacleLine( size_t obstNbrID, const float invTau, bool flip ) { + const Menge::Agents::Obstacle* obst = _nearObstacles[ obstNbrID ].obstacle; + const float LENGTH = obst->length(); + const Vector2 P0 = flip ? obst->getP1() : obst->getP0(); + const Vector2 P1 = flip ? obst->getP0() : obst->getP1(); + const Vector2 obstDir = flip ? -obst->_unitDir : obst->_unitDir; + const bool p0Convex = flip ? obst->p1Convex( true ) : obst->p0Convex( true ); + const bool p1Convex = flip ? obst->p0Convex( true ) : obst->p1Convex( true ); + const Menge::Agents::Obstacle* const leftNeighbor = flip ? obst->_nextObstacle : obst->_prevObstacle; + const Menge::Agents::Obstacle* const rightNeighbor = flip ? obst->_prevObstacle : obst->_nextObstacle; + + const Vector2 relativePosition1 = P0 - _pos; + const Vector2 relativePosition2 = P1 - _pos; + + /* + * Check if velocity obstacle of obstacle is already taken care of by + * previously constructed obstacle ORCA lines. + */ + bool alreadyCovered = false; + + for (size_t j = 0; j < _orcaLines.size(); ++j) { + if (det( invTau * relativePosition1 - _orcaLines[j]._point, _orcaLines[j]._direction) - invTau * _radius >= -Menge::EPS && det(invTau * relativePosition2 - _orcaLines[j]._point, _orcaLines[j]._direction) - invTau * _radius >= -Menge::EPS ) { + alreadyCovered = true; + break; + } + } + + if (alreadyCovered) { + return; + } + + /* Not yet covered. Check for collisions. */ + + const float distSq1 = absSq( relativePosition1 ); + const float distSq2 = absSq( relativePosition2 ); + + const float radiusSq = sqr( _radius ); + + const float s = -(relativePosition1 * obstDir ); + const float distSqLine = absSq(relativePosition1 + s * obstDir ); + + Menge::Math::Line line; + + if (s < 0 && distSq1 <= radiusSq) { + /* Collision with left vertex. Ignore if non-convex. */ + if ( p0Convex ) { + line._point = Vector2(0.f,0.f); + line._direction = norm(Vector2(-relativePosition1.y(), relativePosition1.x())); + _orcaLines.push_back(line); + } + return; + } else if (s > LENGTH && distSq2 <= radiusSq) { + /* Collision with right vertex. Ignore if non-convex + * or if it will be taken care of by neighoring obstace */ + if ( ( obst->_nextObstacle == 0x0 ) || ( p1Convex && det(relativePosition2, obst->_nextObstacle->_unitDir) >= 0) ) { + line._point = Vector2(0.f,0.f); + line._direction = norm(Vector2(-relativePosition2.y(), relativePosition2.x())); + _orcaLines.push_back(line); + } + return; + } else if (s >= 0 && s < LENGTH && distSqLine <= radiusSq) { + /* Collision with obstacle segment. */ + line._point = Vector2(0.f,0.f); + line._direction = -obstDir; + _orcaLines.push_back(line); + return; + } + + /* + * No collision. + * Compute legs. When obliquely viewed, both legs can come from a single + * vertex. Legs extend cut-off line when nonconvex vertex. + */ + + Vector2 leftLegDirection, rightLegDirection; + + /*! + * These booleans short-cut the later code in which we make sure a leg direction does not + * cut into a "neighboring" obstacle. + * + * In the case where the agent is "obliquely viewing" the obstacle near the left or right edge, + * we end up testing one of the legs against obstacle 1 itself. However, by definition, we know that + * both legs lie outside of the obstacle. + */ + bool prevIsCurrent = false; + bool nextIsCurrent = false; + if (s < 0 && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that left vertex defines velocity obstacle. + */ + if ( !p0Convex ) { + /* Ignore obstacle. */ + return; + } + + nextIsCurrent = true; + + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * _radius, relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + rightLegDirection = Vector2(relativePosition1.x() * leg1 + relativePosition1.y() * _radius, -relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + } else if (s > LENGTH && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that right vertex defines velocity obstacle. + */ + if ( !p1Convex ) { + /* Ignore obstacle. */ + return; + } + + prevIsCurrent = true; + + const float leg2 = std::sqrt(distSq2 - radiusSq); + leftLegDirection = Vector2(relativePosition2.x() * leg2 - relativePosition2.y() * _radius, relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * _radius, -relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + } else { + /* Usual situation. */ + if ( p0Convex ) { + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * _radius, relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + } else { + /* Left vertex non-convex; left leg extends cut-off line. */ + leftLegDirection = -obstDir; + } + + if ( p1Convex ) { + const float leg2 = std::sqrt(distSq2 - radiusSq); + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * _radius, -relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + } else { + /* Right vertex non-convex; right leg extends cut-off line. */ + rightLegDirection = obstDir; + } + } + + /* + * Legs can never point into neighboring edge when convex vertex, + * take cutoff-line of neighboring edge instead. If velocity projected on + * "foreign" leg, no constraint is added. + */ + bool isLeftLegForeign = false; + bool isRightLegForeign = false; + + if ( !prevIsCurrent ) { + if ( leftNeighbor != 0x0 ) { + if ( p0Convex && det(leftLegDirection, -leftNeighbor->_unitDir) >= 0.0f) { + /* Left leg points into obstacle. */ + leftLegDirection = -leftNeighbor->_unitDir; + isLeftLegForeign = true; + } + } + } + + if ( !nextIsCurrent ) { + if ( rightNeighbor != 0x0 ) { + if ( p1Convex && det( rightLegDirection, rightNeighbor->_unitDir) <= 0.0f) { + /* Right leg points into obstacle. */ + rightLegDirection = rightNeighbor->_unitDir; + isRightLegForeign = true; + } + } + } + + /* Compute cut-off centers. */ + const Vector2 leftCutoff = invTau * ( prevIsCurrent ? relativePosition2 : relativePosition1 ); + const Vector2 rightCutoff = nextIsCurrent ? leftCutoff : ( invTau * relativePosition2 ); + const Vector2 cutoffVec = rightCutoff - leftCutoff; + const bool obstaclesSame = nextIsCurrent || prevIsCurrent; + + + /* Project current velocity on velocity obstacle. */ + /* Check if current velocity is projected on cutoff circles. */ + const float t = obstaclesSame ? 0.5f : ( (_vel - leftCutoff) * ( cutoffVec / absSq(cutoffVec) ) ); + const float tLeft = ((_vel - leftCutoff) * leftLegDirection); + const float tRight = ((_vel - rightCutoff) * rightLegDirection); + + if ((t < 0.0f && tLeft < 0.0f) || ( obstaclesSame && tLeft < 0.0f && tRight < 0.0f)) { + /* Project on left cut-off circle. */ + const Vector2 unitW = norm( _vel - leftCutoff ); + line._direction = Vector2( unitW.y(), -unitW.x() ); + line._point = leftCutoff + _radius * invTau * unitW; + _orcaLines.push_back(line); + return; + } else if (t > 1.0f && tRight < 0.0f) { + /* Project on right cut-off circle. */ + const Vector2 unitW = norm(_vel - rightCutoff); + line._direction = Vector2(unitW.y(), -unitW.x()); + line._point = rightCutoff + _radius * invTau * unitW; + _orcaLines.push_back(line); + return; + } + + /* + * Project on left leg, right leg, or cut-off line, whichever is closest + * to velocity. + */ + const float distSqCutoff = ((t < 0.0f || t > 1.0f || obstaclesSame) ? std::numeric_limits::infinity() : absSq(_vel - (leftCutoff + t * cutoffVec))); + const float distSqLeft = ((tLeft < 0.0f) ? std::numeric_limits::infinity() : absSq(_vel - (leftCutoff + tLeft * leftLegDirection))); + const float distSqRight = ((tRight < 0.0f) ? std::numeric_limits::infinity() : absSq(_vel - (rightCutoff + tRight * rightLegDirection))); + + if (distSqCutoff <= distSqLeft && distSqCutoff <= distSqRight) { + /* Project on cut-off line. */ + line._direction = -obstDir; + line._point = leftCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } else if (distSqLeft <= distSqRight) { + /* Project on left leg. */ + if ( !isLeftLegForeign) { + line._direction = leftLegDirection; + line._point = leftCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } + } else { + /* Project on right leg. */ + if ( !isRightLegForeign) { + line._direction = -rightLegDirection; + line._point = rightCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } + } + } + + ///////////////////////////////////////////////////////////////////////////// + + size_t Agent::computeORCALines() { + _orcaLines.clear(); + + const float invTimeHorizonObst = 1.0f / _timeHorizonObst; + + /* Create obstacle ORCA lines. */ + for (size_t i = 0; i < _nearObstacles.size(); ++i) { + + const Menge::Agents::Obstacle* obst = _nearObstacles[i].obstacle; + const Vector2 P0 = obst->getP0(); + const Vector2 P1 = obst->getP1(); + const bool agtOnRight = leftOf( P0, P1, _pos ) < 0.f; + obstacleLine( i, invTimeHorizonObst, !agtOnRight && obst->_doubleSided ); + } + + const size_t numObstLines = _orcaLines.size(); + + const float invTimeHorizon = 1.0f / _timeHorizon; + + /* Create agent ORCA lines. */ + for (size_t i = 0; i < _nearAgents.size(); ++i) { + const Agent* const other = static_cast< const Agent *>( _nearAgents[i].agent ); + + const Vector2 relativePosition = other->_pos - _pos; + const Vector2 relativeVelocity = _vel - other->_vel; + + const float distSq = absSq(relativePosition); + const float combinedRadius = _radius + other->_radius; + const float combinedRadiusSq = sqr(combinedRadius); + + Menge::Math::Line line; + Vector2 u; + + if (distSq > combinedRadiusSq) { + /* No collision. */ + const Vector2 w = relativeVelocity - invTimeHorizon * relativePosition; + /* Vector from cutoff center to relative velocity. */ + const float wLengthSq = absSq(w); + + const float dotProduct1 = w * relativePosition; + + if (dotProduct1 < 0.0f && sqr(dotProduct1) > combinedRadiusSq * wLengthSq) { + /* Project on cut-off circle. */ + const float wLength = std::sqrt(wLengthSq); + const Vector2 unitW = w / wLength; + + line._direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeHorizon - wLength) * unitW; + } else { + /* Project on legs. */ + const float leg = std::sqrt(distSq - combinedRadiusSq); + + if (det(relativePosition, w) > 0.0f) { + /* Project on left leg. */ + line._direction = Vector2(relativePosition.x() * leg - relativePosition.y() * combinedRadius, relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } else { + /* Project on right leg. */ + line._direction = -Vector2(relativePosition.x() * leg + relativePosition.y() * combinedRadius, -relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } + + const float dotProduct2 = relativeVelocity * line._direction; + + u = dotProduct2 * line._direction - relativeVelocity; + } + + line._point = _vel + 0.5f * u; + } else { + /* Collision. Project on cut-off circle of time timeStep. */ + const float invTimeStep = 1.0f / Simulator::TIME_STEP; + + /* Vector from cutoff center to relative velocity. */ + const Vector2 w = relativeVelocity - invTimeStep * relativePosition; + + const float wLength = abs(w); + const Vector2 unitW = w / wLength; + + line._direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeStep - wLength) * unitW; + float coopWeight = 0.5f; + line._point = _vel + coopWeight * u; + } + + _orcaLines.push_back(line); + } + return numObstLines; + } + + ///////////////////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + const size_t numObstLines = computeORCALines(); + + Vector2 velPref( _velPref.getPreferredVel() ); + + size_t lineFail = linearProgram2(_orcaLines, _maxSpeed, velPref, false, _velNew); + + if (lineFail < _orcaLines.size()) { + linearProgram3(_orcaLines, numObstLines, lineFail, _maxSpeed, _velNew); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + bool linearProgram1(const std::vector& lines, size_t lineNo, float radius, const Vector2& optVelocity, bool directionOpt, Vector2& result) { + const float dotProduct = lines[lineNo]._point * lines[lineNo]._direction; + const float discriminant = sqr(dotProduct) + sqr(radius) - absSq(lines[lineNo]._point); + + if (discriminant < 0.0f) { + /* Max speed circle fully invalidates line lineNo. */ + return false; + } + + const float sqrtDiscriminant = std::sqrt(discriminant); + float tLeft = -dotProduct - sqrtDiscriminant; + float tRight = -dotProduct + sqrtDiscriminant; + + for (size_t i = 0; i < lineNo; ++i) { + const float denominator = det(lines[lineNo]._direction, lines[i]._direction); + const float numerator = det(lines[i]._direction, lines[lineNo]._point - lines[i]._point); + + if (std::fabs(denominator) <= Menge::EPS ) { + /* Lines lineNo and i are (almost) parallel. */ + if (numerator < 0.0f) { + return false; + } else { + continue; + } + } + + const float t = numerator / denominator; + + if (denominator >= 0.0f) { + /* Line i bounds line lineNo on the right. */ + tRight = std::min(tRight, t); + } else { + /* Line i bounds line lineNo on the left. */ + tLeft = std::max(tLeft, t); + } + + if (tLeft > tRight) { + return false; + } + } + + if (directionOpt) { + /* Optimize direction. */ + if (optVelocity * lines[lineNo]._direction > 0.0f) { + /* Take right extreme. */ + result = lines[lineNo]._point + tRight * lines[lineNo]._direction; + } else { + /* Take left extreme. */ + result = lines[lineNo]._point + tLeft * lines[lineNo]._direction; + } + } else { + /* Optimize closest point. */ + const float t = lines[lineNo]._direction * (optVelocity - lines[lineNo]._point); + + if (t < tLeft) { + result = lines[lineNo]._point + tLeft * lines[lineNo]._direction; + } else if (t > tRight) { + result = lines[lineNo]._point + tRight * lines[lineNo]._direction; + } else { + result = lines[lineNo]._point + t * lines[lineNo]._direction; + } + } + + return true; + } + + ///////////////////////////////////////////////////////////////////////////// + + size_t linearProgram2(const std::vector& lines, float radius, const Vector2& optVelocity, bool directionOpt, Vector2& result) { + if (directionOpt) { + /* + * Optimize direction. Note that the optimization velocity is of unit + * length in this case. + */ + result = optVelocity * radius; + } else if (absSq(optVelocity) > sqr(radius)) { + /* Optimize closest point and outside circle. */ + result = norm(optVelocity) * radius; + } else { + /* Optimize closest point and inside circle. */ + result = optVelocity; + } + + for (size_t i = 0; i < lines.size(); ++i) { + if (det(lines[i]._direction, lines[i]._point - result) > 0.0f) { + /* Result does not satisfy constraint i. Compute new optimal result. */ + const Vector2 tempResult = result; + if (!linearProgram1(lines, i, radius, optVelocity, directionOpt, result)) { + result = tempResult; + return i; + } + } + } + + return lines.size(); + } + + ///////////////////////////////////////////////////////////////////////////// + + void linearProgram3(const std::vector& lines, size_t numObstLines, size_t beginLine, float radius, Vector2& result) { + float distance = 0.0f; + + for (size_t i = beginLine; i < lines.size(); ++i) { + if (det(lines[i]._direction, lines[i]._point - result) > distance) { + /* Result does not satisfy constraint of line i. */ + std::vector projLines(lines.begin(), lines.begin() + numObstLines); + + for (size_t j = numObstLines; j < i; ++j) { + Menge::Math::Line line; + + float determinant = det(lines[i]._direction, lines[j]._direction); + + if (std::fabs(determinant) <= Menge::EPS ) { + /* Math::Line i and line j are parallel. */ + if (lines[i]._direction * lines[j]._direction > 0.0f) { + /* Line i and line j point in the same direction. */ + continue; + } else { + /* Line i and line j point in opposite direction. */ + line._point = 0.5f * (lines[i]._point + lines[j]._point); + } + } else { + line._point = lines[i]._point + (det(lines[j]._direction, lines[i]._point - lines[j]._point) / determinant) * lines[i]._direction; + } + + line._direction = norm(lines[j]._direction - lines[i]._direction); + projLines.push_back(line); + } + + const Vector2 tempResult = result; + if (linearProgram2(projLines, radius, Vector2(-lines[i]._direction.y(), lines[i]._direction.x()), true, result) < projLines.size()) { + /* This should in principle not happen. The result is by definition + * already in the feasible region of this linear program. If it fails, + * it is due to small floating point error, and the current result is + * kept. + */ + result = tempResult; + } + + distance = det(lines[i]._direction, lines[i]._point - result); + } + } + } +} // namespace ORCA diff --git a/src/Menge/MengeCore/Orca/ORCAAgent.h b/src/Menge/MengeCore/Orca/ORCAAgent.h new file mode 100644 index 00000000..e5866789 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCAAgent.h @@ -0,0 +1,166 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCAAgent.h + * @brief Contains the PedVOAgent class. + */ + +#ifndef __ORCA_AGENT_H__ +#define __ORCA_AGENT_H__ + +#include "BaseAgent.h" +#include "Math/Line.h" + +namespace ORCA { + /*! + * @brief Defines an agent in the simulation. + */ + class Agent : public Menge::Agents::BaseAgent { + public: + /*! + * @brief Constructor + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief Based on the neighbors, computes the ORCA lines + * + * @returns The total number of obstacle lines + */ + size_t computeORCALines(); + + /*! + * @brief The set of ORCA constraints. + */ + std::vector _orcaLines; + + /*! + * @brief The time horizon for inter-agent interactions. + */ + float _timeHorizon; + + /*! + * @brief The time horizon for agent-obstacle interactions. + */ + float _timeHorizonObst; + + // DEFAULT VALUES FOR THE AGENT PARAMTERS + /*! + * @brief The default time horizon for inter-agent interactions. + */ + static const float TAU; + + /*! + * @brief The default time horizon for agent-obstacle interactions. + */ + static const float TAU_OBST; + + friend class Simulator; + + protected: + /*! + * @brief Constructs an ORCA line for the given obstacle + * under the assumption that the agent is on its right side. + * If appropriate, it adds the obstacle to the set of orca lines. + * + * @param obstNbrID The index of the near-by obstacle to test. + * @param invTau 1 / _timeHorizonObst - the inverse of the + * time horizon for obstacles. + * @param flip The agent is on the left side of this obstacle. + */ + void obstacleLine( size_t obstNbrID, const float invTau, bool flip ); + }; + + /*! + * @brief Solves a one-dimensional linear program on a specified line + * subject to linear constraints defined by lines and a circular + * constraint. + * + * @param lines Lines defining the linear constraints. + * @param lineNo The specified line constraint. + * @param radius The radius of the circular constraint. + * @param optVelocity The optimization velocity. + * @param directionOpt True if the direction should be optimized. + * @param result A reference to the result of the linear program. + * @returns True if successful. + */ + bool linearProgram1(const std::vector& lines, size_t lineNo, + float radius, const Vector2& optVelocity, + bool directionOpt, Vector2& result); + + /*! + * @brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * + * @param lines Lines defining the linear constraints. + * @param radius The radius of the circular constraint. + * @param optVelocity The optimization velocity. + * @param directionOpt True if the direction should be optimized. + * @param result A reference to the result of the linear program. + * @returns The number of the line it fails on, and the number of lines if successful. + */ + size_t linearProgram2(const std::vector& lines, float radius, + const Vector2& optVelocity, bool directionOpt, + Vector2& result); + + /*! + * @brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * + * @param lines Lines defining the linear constraints. + * @param numObstLines Count of obstacle lines. + * @param beginLine The line on which the 2-d linear program failed. + * @param radius The radius of the circular constraint. + * @param result A reference to the result of the linear program. + */ + void linearProgram3(const std::vector& lines, size_t numObstLines, size_t beginLine, + float radius, Vector2& result); +} // namespace ORCA + +#endif diff --git a/src/Menge/MengeCore/Orca/ORCAAgentContext.h b/src/Menge/MengeCore/Orca/ORCAAgentContext.h new file mode 100644 index 00000000..64a58884 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCAAgentContext.h @@ -0,0 +1,66 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCAAgentContext.h + * @brief A basic context for interacting with and displaying + * ORCA agent parameters + */ + +#ifndef __ORCA_AGENT_CONTEXT_H__ +#define __ORCA_AGENT_CONTEXT_H__ + +#include "ORCATypeAgentContext.h" +#include "ORCAAgent.h" + +namespace ORCA { + /*! + * @brief Specialization of the ORCA context for ORCA::Agent. + */ + typedef ORCATypeAgentContext< Agent > AgentContext; +} + +//////////////////////////////////////////////////////////////// +// Implementation of ORCAAgentContext +//////////////////////////////////////////////////////////////// + +// Specialization +template <> +inline std::string ORCATypeAgentContext< ORCA::Agent >::contextName() const { return "ORCA"; } + +#endif // __ORCA_AGENT_CONTEXT_H__ diff --git a/src/Menge/MengeCore/Orca/ORCADBEntry.cpp b/src/Menge/MengeCore/Orca/ORCADBEntry.cpp new file mode 100644 index 00000000..6a20ba3a --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCADBEntry.cpp @@ -0,0 +1,89 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ORCADBEntry.h" +#include "SimulatorDB.h" +#include "ORCAAgentContext.h" +#include "ORCAInitializer.h" +#include "ORCASimulator.h" +#include "SimSystem.h" +#include "BaseAgentContext.h" + +namespace ORCA { + ///////////////////////////////////////////////////////////////////////////// + // Implementation of ORCAD::BEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Based on the ORCA collision avoidance algorithm"; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on ORCA collision avoidance\n" + "\tBased on the RVO2 library available at http:\\\\gamma.cs.unc.edu\\RVO2"; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "ORCA"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::BaseAgentContext * DBEntry::contextFromSystem( Menge::SimSystem * simSystem ) { + return new AgentContext( simSystem->getVisAgents(), (unsigned int)simSystem->getAgentCount() ); + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// + +} // namespace ORCA + diff --git a/src/Menge/MengeCore/Orca/ORCADBEntry.h b/src/Menge/MengeCore/Orca/ORCADBEntry.h new file mode 100644 index 00000000..a94fe824 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCADBEntry.h @@ -0,0 +1,129 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCADBEntry.h + * @brief The simulator database entry for the ORCA pedestrian model. + */ + +#ifndef __ORCA_DB_ENTRY_H__ +#define __ORCA_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "ORCA.h" + +namespace ORCA { + /*! + * @brief The simulator database entry for the ORCA simulator. + */ + class DBEntry : public Menge::SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "orca"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Menge::Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Menge::Agents::AgentInitializer * getAgentInitalizer() const; + + protected: + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * If the provided system is not, in fact, a pointer to a SimSystem for the + * appropriate simulator type, this function will report failure. Furthermore, + * the default implementation is to return a BaseAgentContext. If the + * simulator comes with a novel context, this function should be overridden + * in the derived SimulatorDBEntry. + * + * @param simSystem The system which tracks the agents. This should be + * the same system which was returned by a call to + * Menge::SimulatorDBEntry::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. If the system is of + * the wrong type (or if there is any other problem), NULL is returned. + */ + virtual Menge::BaseAgentContext * contextFromSystem( Menge::SimSystem * simSystem ); + }; +} // namespace ORCA +#endif // __ORCA_DB_ENTRY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Orca/ORCAInitializer.cpp b/src/Menge/MengeCore/Orca/ORCAInitializer.cpp new file mode 100644 index 00000000..8114c19c --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCAInitializer.cpp @@ -0,0 +1,141 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ORCAInitializer.h" +#include "ORCAAgent.h" +#include "Math/RandGenerator.h" + +namespace ORCA { + + //////////////////////////////////////////////////////////////// + // Implementation of ORCA::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float TAU = 2.5f; ///< The default value for tau (the time horizon w.r.t. other agents). + const float TAU_OBST = 0.15f; ///< The default value for tau obstacles (the time horizon w.r.t. obstacles). + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Menge::Agents::AgentInitializer() { + _timeHorizon = new ConstFloatGenerator( TAU ); + _timeHorizonObst = new ConstFloatGenerator( TAU_OBST ); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) : Menge::Agents::AgentInitializer(init) { + _timeHorizon = init._timeHorizon->copy(); + _timeHorizonObst = init._timeHorizonObst->copy(); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _timeHorizon; + delete _timeHorizonObst; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Menge::Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_timeHorizon = _timeHorizon->getValue(); + a->_timeHorizonObst = _timeHorizonObst->getValue(); + + return Menge::Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "ORCA" ) || Menge::Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + Menge::Agents::AgentInitializer::ParseResult result = IGNORED; + if ( paramName == "tau" ) { + result = constFloatGenerator( _timeHorizon, value ); + } else if ( paramName == "tauObst" ) { + result = constFloatGenerator( _timeHorizonObst, value ); + } + + if ( result == FAILURE ) { + Menge::logger << Menge::Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Menge::Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + Menge::Agents::AgentInitializer::ParseResult result = IGNORED; + if ( propName == "tau" ) { + result = getFloatGenerator( _timeHorizon, node ); + } else if ( propName == "tauObst" ) { + result = getFloatGenerator( _timeHorizonObst, node ); + } + + if ( result == FAILURE ) { + Menge::logger << Menge::Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Menge::Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _timeHorizon ) delete _timeHorizon; + _timeHorizon = new ConstFloatGenerator( TAU ); + if ( _timeHorizonObst ) delete _timeHorizonObst; + _timeHorizonObst = new ConstFloatGenerator( TAU_OBST ); + Menge::Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace ORCA diff --git a/src/Menge/MengeCore/Orca/ORCAInitializer.h b/src/Menge/MengeCore/Orca/ORCAInitializer.h new file mode 100644 index 00000000..d67b6f0e --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCAInitializer.h @@ -0,0 +1,173 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCAInitializer.h + * @brief The AgentInitializer for the ORCA simulator. + */ +#ifndef __ORCA_INITIALIZER_H__ +#define __ORCA_INITIALIZER_H__ + +#include "AgentInitializer.h" + +namespace ORCA { + /*! + * @brief Class which determines the agent properties for each new ORCA agent. + */ + class AgentInitializer : public Menge::Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The AgentInitializer to copy all values + * from. + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Menge::Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual Menge::Agents::AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `` + * parameter set defined in the base class (or any other derived dependency). + * + * @param tagName The name of the tag to test. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Menge::Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given `` tag. + * + * As a pre-condition to this function, the XML node contains a `` + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief The time horizon for predicting agent collisions + */ + FloatGenerator * _timeHorizon; + + /*! + * @brief The time horizon for predicting obstacle collisions + */ + FloatGenerator * _timeHorizonObst; + }; +} // namespace ORCA + + +#endif // __OPENSTEER_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Orca/ORCASimulator.cpp b/src/Menge/MengeCore/Orca/ORCASimulator.cpp new file mode 100644 index 00000000..ed3662c9 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCASimulator.cpp @@ -0,0 +1,48 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ORCASimulator.h" +#include "ORCAAgent.h" + +namespace ORCA { + //////////////////////////////////////////////////////////////// + // Implementation of ORCA::Simulator + //////////////////////////////////////////////////////////////// + +} // namespace ORCA + diff --git a/src/Menge/MengeCore/Orca/ORCASimulator.h b/src/Menge/MengeCore/Orca/ORCASimulator.h new file mode 100644 index 00000000..c5637ec8 --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCASimulator.h @@ -0,0 +1,70 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCASimulator.h + * @brief Contains the ORCA::Simulator class. + */ + +#ifndef __ORCA_SIMULATOR_H__ +#define __ORCA_SIMULATOR_H__ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "ORCAAgent.h" + +/*! + * @namespace ORCA + * @brief The namespace for the ORCA local collision avoidance model. + */ +namespace ORCA { + /*! + * @brief Defines the simulator operating on ORCA::Agent. + */ + class Simulator : public Menge::Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructs a simulator instance. + */ + Simulator(): Menge::Agents::SimulatorBase< Agent >() {} + + private: + friend class Agent; + }; +} // namespace ORCA +#endif diff --git a/src/Menge/MengeCore/Orca/ORCATypeAgentContext.h b/src/Menge/MengeCore/Orca/ORCATypeAgentContext.h new file mode 100644 index 00000000..12de9c8f --- /dev/null +++ b/src/Menge/MengeCore/Orca/ORCATypeAgentContext.h @@ -0,0 +1,525 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ORCATypeAgentContext.h + * @brief A basic context for interacting with and displaying + * ORCA-type agent parameters. + * + * ORCA-type agents are those that solve w.r.t. a set of linear constraints + * this context gives some basic functionality for displaying those constraints + */ + +#ifndef __ORCA_TYPE_AGENT_CONTEXT_H__ +#define __ORCA_TYPE_AGENT_CONTEXT_H__ + +#include "BaseAgentContext.h" +#include "shapes.h" +#include "VisAgent.h" +#include +#include + +/*! + * @brief Context class for displaying various aspects of the + * ORCA-type agent computation. + */ +template < class Agent > +class ORCATypeAgentContext : public Menge::BaseAgentContext { +public: + /*! + * @brief Construtor + * + * @param agents An array of pointers to VisAgent instances. + * @param agtCount The number of agents contained in the array. + */ + ORCATypeAgentContext( Menge::VisAgent ** agents, unsigned int agtCount ); + + /*! + * @brief Returns the name of the context for display. + * + * @returns The name of this context. + */ + virtual std::string contextName() const { return "UNDEFINED ORCA TYPE"; } + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual Menge::SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Allow the context to update any time-dependent state it might have to + * the given global time. + */ + virtual void update(); + +protected: + + /*! + * @brief Draw context elements into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( bool select=false ); + + /*! + * @brief Helper function for drawing a halfplane + * @param line The line object which defines the half plane + * @param pos The relative position to draw the plane + * Typically the position of the agent on which the half-plane + * is applied. + * @param r The red component of the half plane color + * @param g The green component of the half plane color + * @param b The blue component of the half plane color + * @param Y Value, on the y-axis (in world coordinates), of the + * plane on which to draw the half plane + */ + void drawHalfPlane( const Menge::Math::Line & line, const Vector2 & pos, float r, float g, float b, float Y ) const; + + /*! + * @brief Draws the given ORCA line for the given agent + * + * @param agent A pointer to the agent to whom this line applies + * @param line The actual line + * @param isAgent A boolean reporting if the orca line comes from an agent. + * true --> agent, false --> obstacle + */ + void drawORCALine( const Agent * agent, const Menge::Math::Line & line, bool isAgent ) const; + + /*! + * @brief Draw the optimized velocity for the current set of orca lines + * + * @param agent A pointer to the agent for which the velocity is drawn + * computeNewVelocity will be called on the agent + */ + void drawOptVelocity( Agent * agent ) const; + + /*! + * @brief Creates a formatted string to be printed in the context + * for a particular agent + * + * @param agent A pointer to the agent for which the information is + * displayed. + * @returns A formatted string for display in the context's 2D gui. + */ + virtual std::string agentText( const Menge::Agents::BaseAgent * agent ) const; + + /*! + * @brief Determines if the ORCA lines are drawn + */ + bool _showOrcaLines; + + /*! + * @brief Function for drawing the ORCA lines acting on agt + * + * @param agt A pointer to the agent whose ORCA lines will be drawn. + */ + void drawORCALines( const Agent * agt ) const; + + /*! + * @brief Determines if the ORCA line construction is visualized + */ + bool _visualizeORCA; + + /*! + * @brief The agent to visualize + */ + size_t _visNbrID; + + /*! + * @brief The function that draws the visualization of the orca construction + * + * @param agt A pointer to the agent for whom the *computation* of + * a single ORCA line is illustrated. + */ + void visORCA( const Agent * agt ) const; +}; + +//////////////////////////////////////////////////////////////// + +template< class Agent > +ORCATypeAgentContext< Agent >::ORCATypeAgentContext( Menge::VisAgent ** agents, unsigned int agtCount ): Menge::BaseAgentContext(agents,agtCount), _showOrcaLines(false),_visualizeORCA(false),_visNbrID(0) { +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > + void ORCATypeAgentContext< Agent >::update() { + if ( this->_selected && _visNbrID ) { + const Agent * agt = dynamic_cast< const Agent * >( this->_selected->getAgent() ); + if ( _visNbrID > 0 ) { + size_t NBR_COUNT = agt->_nearAgents.size(); + if ( _visNbrID > NBR_COUNT ) { + _visNbrID = NBR_COUNT; + } + } + } +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +Menge::SceneGraph::ContextResult ORCATypeAgentContext< Agent >::handleKeyboard( SDL_Event & e ) { + Menge::SceneGraph::ContextResult result = BaseAgentContext::handleKeyboard( e ); + if ( !result.isHandled() ) { + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + if ( e.type == SDL_KEYDOWN ) { + if ( noMods ) { + if ( e.key.keysym.sym == SDLK_c ) { + _showOrcaLines = !_showOrcaLines; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_z ) { + _visualizeORCA = !_visualizeORCA; + _visNbrID = 0; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_UP ) { + if ( _visualizeORCA && this->_selected ) { + const Agent * agt = dynamic_cast< const Agent * >( this->_selected->getAgent() ); + ++_visNbrID; + if ( _visNbrID >= agt->_nearAgents.size() ) _visNbrID = 0; + result.set( true, true ); + } + } else if ( e.key.keysym.sym == SDLK_DOWN ) { + if ( _visualizeORCA && this->_selected ) { + const Agent * agt = dynamic_cast< const Agent * >( this->_selected->getAgent() ); + if ( _visNbrID == 0 ) _visNbrID = agt->_nearAgents.size() - 1; + else --_visNbrID; + result.set( true, true ); + } + } + } + } + } + return result; +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::draw3DGL( bool select ) { + Menge::BaseAgentContext::draw3DGL( select ); + if ( !select && this->_selected ) { + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + glDepthMask( GL_FALSE ); + glDisable( GL_DEPTH_TEST ); + const Agent * agt = dynamic_cast< const Agent * >( this->_selected->getAgent() ); + drawORCALines( agt ); + visORCA( agt ); + glPopAttrib(); + } +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +std::string ORCATypeAgentContext< Agent >::agentText( const Menge::Agents::BaseAgent * agt ) const { + const Agent * agent = dynamic_cast< const Agent * >( agt ); + std::string m = Menge::BaseAgentContext::agentText( agent ); + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + + ss << "\n_________________________"; + ss << "\nDraw OR(C)A lines"; + if ( _showOrcaLines ) { + const size_t LINE_COUNT = agent->_orcaLines.size(); + const size_t AGT_COUNT = agent->_nearAgents.size(); + const size_t OBST_COUNT = LINE_COUNT - AGT_COUNT; + ss << "\n " << OBST_COUNT << " obstacle lines"; + ss << "\n " << AGT_COUNT << " agent lines"; + } + ss << "\nVisuali(z)e ORCA"; + if ( _visualizeORCA ) { + if ( agent->_nearAgents.size() == 0 ) { + ss << "\n No nearby agents."; + } else { + size_t id = (agent->_nearAgents[_visNbrID].agent)->_id; + ss << "\n Showing agent: " << id << " (up/down arrow to change)"; + } + } + return m + ss.str(); +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::drawHalfPlane( const Menge::Math::Line & line, const Vector2 & pos, float r, float g, float b, float Y ) const { + const float DIST = 35.f; + Vector2 norm( -line._direction.y(), line._direction.x() ); + Vector2 p0 = line._point + line._direction * DIST + pos; + Vector2 p1 = p0 - norm * DIST; + Vector2 p2 = p1 - line._direction * ( 2 * DIST ); + Vector2 p3 = p2 + norm * DIST; + + glColor4f( r, g, b, 0.1f ); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glEnable( GL_BLEND ); + + glBegin( GL_QUADS ); + glVertex3f( p0.x(), Y, p0.y() ); + glVertex3f( p1.x(), Y, p1.y() ); + glVertex3f( p2.x(), Y, p2.y() ); + glVertex3f( p3.x(), Y, p3.y() ); + glEnd(); + glDisable( GL_BLEND ); + + glBegin( GL_LINES ); + glVertex3f( p0.x(), Y, p0.y() ); + glVertex3f( p3.x(), Y, p3.y() ); + glEnd(); +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::drawORCALines( const Agent * agent ) const { + if ( _showOrcaLines && this->_selected ) { + Agent * agt = const_cast< Agent * >( agent ); + agt->computeORCALines(); + const size_t LINE_COUNT = agt->_orcaLines.size(); + const size_t FIRST_AGENT = LINE_COUNT - agt->_nearAgents.size(); + const float DIST = 35.f; + + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glEnable( GL_BLEND ); + // Obstacle color + glColor4f( 0.75f, 0.75f, 0.75f, 0.1f ); + glBegin( GL_QUADS ); + for ( size_t i = 0; i < LINE_COUNT; ++i ) { + // Agent color + if ( i == FIRST_AGENT ) { + glColor4f( 1.f, 0.f, 0.f, 0.1f ); + } + const Menge::Math::Line & line = agt->_orcaLines[ i ]; + // Find the nearest point on the orca line to the agent -- use that as the center + Vector2 norm( -line._direction.y(), line._direction.x() ); + float t = line._direction * ( -line._point ); + Vector2 nearPt = line._point + t * line._direction; + Vector2 p0 = nearPt + line._direction * DIST + agt->_pos; + Vector2 p1 = p0 - norm * DIST; + Vector2 p2 = p1 - line._direction * ( 2 * DIST ); + Vector2 p3 = p2 + norm * DIST; + + glVertex3f( p0.x(), this->Y, p0.y() ); + glVertex3f( p1.x(), this->Y, p1.y() ); + glVertex3f( p2.x(), this->Y, p2.y() ); + glVertex3f( p3.x(), this->Y, p3.y() ); + } + glEnd(); + glDisable( GL_BLEND ); + + glColor4f( 0.75f, 0.75f, 0.75f, 0.1f ); + glBegin( GL_LINES ); + for ( size_t i = 0; i < LINE_COUNT; ++i ) { + if ( i == FIRST_AGENT ) { + glColor4f( 1.f, 0.f, 0.f, 0.1f ); + } + const Menge::Math::Line & line = agt->_orcaLines[ i ]; + float t = line._direction * ( -line._point ); + Vector2 nearPt = line._point + t * line._direction; + Vector2 p0 = nearPt + line._direction * DIST + agt->_pos; + Vector2 p1 = nearPt - line._direction * DIST + agt->_pos; + glVertex3f( p0.x(), this->Y, p0.y() ); + glVertex3f( p1.x(), this->Y, p1.y() ); + } + glEnd(); + // Label the orca lines from agents + glColor4f( 1.f, 0.f, 0.f, 1.f ); + for ( size_t i = FIRST_AGENT; i < LINE_COUNT; ++i ) { + std::stringstream ss; + const Menge::Agents::BaseAgent * nbr = agent->_nearAgents[ i - FIRST_AGENT ].agent; + ss << nbr->_id; + Vector2 d = agent->_orcaLines[ i ].nearestPt( Vector2(0.f,0.f) ); + Vector2 p = d + agent->_pos; + this->writeTextRadially( ss.str(), p, d, true ); + this->writeAlignedText( ss.str(), nbr->_pos, Menge::SceneGraph::TextWriter::CENTERED, true ); + } + } +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::visORCA( const Agent * agt ) const { + if ( _visualizeORCA && this->_selected ) { + if ( agt->_nearAgents.size() > 0 ) { + Vector2 velPref = agt->_velPref.getPreferredVel(); + const float RAD_TO_DEG = 180.f * 3.1415927f; + glColor3f( 0.1f, 1.f, 0.1f ); + Agent * agent = const_cast< Agent * >( agt ); + agent->computeORCALines(); + const Agent * nbr = static_cast< const Agent * >( agent->_nearAgents[ _visNbrID ].agent ); + float R = agent->_radius + nbr->_radius; + Vector2 disp = nbr->_pos - agent->_pos; + float dist = abs( disp ); + Vector2 dir = disp / dist; + Vector2 perp( -dir.y(), dir.x() ); + + // Compute the tangent portions of the minkowski sum + float cosPhi = R / dist; + float sinPhi = sqrtf( 1 - cosPhi * cosPhi ); + float cx = cosPhi * -dir.x(); + float sx = sinPhi * -dir.x(); + float cy = cosPhi * -dir.y(); + float sy = sinPhi * -dir.y(); + + Vector2 r0 = disp + R * Vector2( cx - sy, sx + cy ); + Vector2 l0 = disp + R * Vector2( cx + sy, -sx + cy ); + // modify the positions of r0 and l0 so that they project onto the center + // + float l = dist / ( r0 * dir ); + r0 *= l; + l0 *= l; + r0 += agent->_pos; + l0 += agent->_pos; + + // What's the closest circle? + const float TAU = agent->_timeHorizon; + float minVel = dist / TAU; + float Rmin = R / TAU; + Vector2 center( agent->_pos + dir * minVel ); + // First, draw leading circle + glPushMatrix(); + glTranslatef( center.x(), this->Y, center.y() ); + Menge::SceneGraph::Circle::drawCircle( Rmin, 0.1f, 1.f, 0.1f, 0.75f, GL_LINE ); + glPopMatrix(); + + Vector2 r1 = center + Rmin * Vector2( cx - sy, sx + cy ); + Vector2 l1 = center + Rmin * Vector2( cx + sy, -sx + cy ); + + glBegin( GL_LINES ); + glVertex3f( r0.x(), this->Y, r0.y() ); + glVertex3f( r1.x(), this->Y, r1.y() ); + glVertex3f( l0.x(), this->Y, l0.y() ); + glVertex3f( l1.x(), this->Y, l1.y() ); + glEnd(); + + // Use right of way to compute velocities + float row = agent->_priority - nbr->_priority; + Vector2 agtVel = agent->_vel; + Vector2 nbrVel = nbr->_vel; + Vector2 nbrVelPref = nbr->_velPref.getPreferredVel(); + if ( row > 0.f ) { + // agent's advantage + row = row > 1.f ? 1.f : row; + if ( dir * velPref > dir * agent->_vel ) { + agtVel = velPref * row + ( 1.f - row ) * agent->_vel; + } + } else if ( row < 0.f ) { + // nbr's advantage + row = row < -1.f ? 1.f : -row; + if ( dir * nbrVelPref < dir * nbr->_vel ) { + nbrVel = nbrVelPref * row + ( 1.f - row ) * nbr->_vel; + } + } + + // Other guy's velocity + glColor3f( 0.1f, 0.1f, 0.8f ); + glBegin( GL_LINES ); + glVertex3f( nbr->_pos.x(), this->Y, nbr->_pos.y() ); + glVertex3f( nbr->_pos.x() + nbrVel.x(), this->Y, nbr->_pos.y() + nbrVel.y() ); + glEnd(); + this->writeTextRadially( "v_j", nbr->_pos + nbrVel, nbrVel, true); + + // My velocity + glColor3f( 0.1f, 0.8f, 0.1f ); + glBegin( GL_LINES ); + glVertex3f( agent->_pos.x(), this->Y, agent->_pos.y() ); + glVertex3f( agent->_pos.x() + agtVel.x(), this->Y, agent->_pos.y() + agtVel.y() ); + glEnd(); + this->writeTextRadially( "v_i", agent->_pos + agtVel, agtVel, true ); + + // Relative velocity + glColor3f( 0.1f, 0.8f, 0.8f ); + glBegin( GL_LINES ); + Vector2 rel = agtVel - nbrVel; + glVertex3f( agent->_pos.x(), this->Y, agent->_pos.y() ); + glVertex3f( agent->_pos.x() + rel.x(), this->Y, agent->_pos.y() + rel.y() ); + glEnd(); + this->writeTextRadially( "v_ij", agent->_pos + rel, rel, true ); + + + // Draw the ORCA line + // Determine which line it is + size_t NBR_COUNT = agent->_nearAgents.size(); + size_t FIRST_NBR = agent->_orcaLines.size() - NBR_COUNT; + drawORCALine( agent, agent->_orcaLines[ FIRST_NBR + _visNbrID ], true ); + + // optimized velocity in transformed space + drawOptVelocity( agent ); + } + } +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::drawORCALine( const Agent * agent, const Menge::Math::Line & line, bool isAgent ) const { + if ( isAgent ) { + drawHalfPlane( line, agent->_pos, 1.f, 0.f, 0.f, this->Y ); + } else { + drawHalfPlane( line, agent->_pos, 0.75f, 0.75f, 0.75f, this->Y ); + } +} + +//////////////////////////////////////////////////////////////// + +template< class Agent > +void ORCATypeAgentContext< Agent >::drawOptVelocity( Agent * agent ) const { + // Draw the optimized velocity (transformed and untransformed + agent->computeNewVelocity(); + // NORMAL space + glPushAttrib( GL_POINT_BIT ); + glPointSize( 3.f ); + glColor3f( 0.2f, 0.2f, 1.f ); + glBegin( GL_POINTS ); + glVertex3f( agent->_pos.x() + agent->_velNew.x(), this->Y, agent->_pos.y() + agent->_velNew.y() ); + glEnd(); + this->writeTextRadially( " v_new ", agent->_pos + agent->_velNew, agent->_velNew, true ); +} + + +#endif // __ORCA_TYPE_AGENT_CONTEXT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PedVO/PedVO.h b/src/Menge/MengeCore/PedVO/PedVO.h new file mode 100644 index 00000000..7432954e --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVO.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVO.h + * @brief The definition of the PedVO pedestrian plug-in + */ + +#ifndef __PEDVO_H__ +#define __PEDVO_H__ + +#include "PedVOSimulator.h" +#include "PedVOAgent.h" + +#endif diff --git a/src/Menge/MengeCore/PedVO/PedVOAgent.cpp b/src/Menge/MengeCore/PedVO/PedVOAgent.cpp new file mode 100644 index 00000000..def4a843 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOAgent.cpp @@ -0,0 +1,759 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include +#include + +#include "PedVOAgent.h" +#include "PedVOSimulator.h" +#include "mengeCommon.h" + +namespace PedVO { + + /////////////////////////////////////////////////////////////////////// + // Implementation of PedVO::Agent + /////////////////////////////////////////////////////////////////////// + + // AGENT DEFAULT PARAMETERS + const float Agent::TAU = 2.5f; + const float Agent::TAU_OBST = 0.15f; + const float Agent::TURN_BIAS = 1.f; + const float Agent::STRIDE_FACTOR = 1.57f; + const float Agent::STRIDE_BUFFER = 0.5f; + + /////////////////////////////////////////////////////////////////////// + + Agent::Agent(): Menge::Agents::BaseAgent() { + _timeHorizon = TAU; + _timeHorizonObst = TAU_OBST; + _turningBias = TURN_BIAS; + _denseAware = true; + setStrideParameters( STRIDE_FACTOR, STRIDE_BUFFER ); + } + + /////////////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + //////////////////////////////////////////////////////////////// + + void Agent::setStrideParameters( float factor, float buffer ) { + _strideConst = 0.5f * ( 1.f + buffer ) / factor ; + _speedConst = 1.f / ( _strideConst * _strideConst ); + } + + //////////////////////////////////////////////////////////////// + + void Agent::adaptPreferredVelocity() { + if ( _denseAware ) { + float prefSpeed = _velPref.getSpeed(); + Vector2 prefDir( _velPref.getPreferred() ); + float availSpace = 1e6f; // start assuming there is infinite space + + float strideLen = 1.f; // Not the speed-dependent stride length, but rather the mid-point of the + // elliptical personal space. + Vector2 critPt = _pos + strideLen * prefDir; + float density = 0.f; + // For now, assume some constants + const float area = 1.5f; + const float areaSq2Inv = 1.f / ( 2 * area * area ); + const float sqrt2Pi = sqrtf( Menge::TWOPI ); + const float norm = 1.f / ( area * sqrt2Pi ); + + // AGENTS + for ( size_t i = 0; i < _nearAgents.size(); ++i ) { + const BaseAgent* const other = _nearAgents[i].agent; + Vector2 critDisp = other->_pos - critPt; + Vector2 yComp = ( critDisp * prefDir ) * prefDir; // dot project gets projection, in the preferred direction + Vector2 xComp = ( critDisp - yComp ) * 2.5f; // penalize displacement perpindicular to the preferred direction + critDisp.set( xComp + yComp ); + float distSq = absSq( critDisp ); + density += norm * expf( -distSq * areaSq2Inv ); + } + //// OBSTACLES + const float OBST_AREA = 0.75f; + const float OBST_AREA_SQ_INV = 1.f / ( 2 * OBST_AREA * OBST_AREA ); + const float OBST_NORM = 1.f / ( OBST_AREA * sqrt2Pi ); + const float OBST_SCALE = norm;// * 6.25f; // what is the "density" of an obstacle? + for ( size_t i = 0; i < _nearObstacles.size(); ++i ) { + const Menge::Agents::Obstacle* const obst = _nearObstacles[i].obstacle; + Vector2 nearPt; + float distSq; // set by distanceSqToPoint + if ( obst->distanceSqToPoint( critPt, nearPt, distSq ) == Menge::Agents::Obstacle::LAST ) continue; + + if ( ( nearPt - _pos ) * prefDir < 0.f ) continue; + density += OBST_SCALE * expf( -distSq * OBST_AREA_SQ_INV ); + } + + const float AGENT_WIDTH = 0.48f; + if ( density < 0.001f ) { + availSpace = 100.f; + } else { + availSpace = AGENT_WIDTH / density ; + } + + // Compute the maximum speed I could take for the available space + float maxSpeed = _speedConst * availSpace * availSpace; + if ( maxSpeed < prefSpeed ) _velPref.setSpeed( maxSpeed ); + } + } + + /////////////////////////////////////////////////////////////////////// + + /* Compute the ORCA lines for the neighboring obstacles and agents */ + size_t Agent::computeORCALines() { + Vector2 junk1, junk2; + float junk; + return computeORCALines( junk1, junk2, junk ); + } + + ///////////////////////////////////////////////////////////////////////////// + + void Agent::obstacleLine( size_t obstNbrID, const float invTau, bool flip ) { + const Menge::Agents::Obstacle* obst = _nearObstacles[ obstNbrID ].obstacle; + const float LENGTH = obst->length(); + const Vector2 P0 = flip ? obst->getP1() : obst->getP0(); + const Vector2 P1 = flip ? obst->getP0() : obst->getP1(); + const Vector2 obstDir = flip ? -obst->_unitDir : obst->_unitDir; + const bool p0Convex = flip ? obst->p1Convex( true ) : obst->p0Convex( true ); + const bool p1Convex = flip ? obst->p0Convex( true ) : obst->p1Convex( true ); + const Menge::Agents::Obstacle* const leftNeighbor = flip ? obst->_nextObstacle : obst->_prevObstacle; + const Menge::Agents::Obstacle* const rightNeighbor = flip ? obst->_prevObstacle : obst->_nextObstacle; + + const Vector2 relativePosition1 = P0 - _pos; + const Vector2 relativePosition2 = P1 - _pos; + + /* + * Check if velocity obstacle of obstacle is already taken care of by + * previously constructed obstacle ORCA lines. + */ + bool alreadyCovered = false; + + for (size_t j = 0; j < _orcaLines.size(); ++j) { + if (det( invTau * relativePosition1 - _orcaLines[j]._point, _orcaLines[j]._direction) - invTau * _radius >= -Menge::EPS && det(invTau * relativePosition2 - _orcaLines[j]._point, _orcaLines[j]._direction) - invTau * _radius >= -Menge::EPS) { + alreadyCovered = true; + break; + } + } + + if (alreadyCovered) { + return; + } + + /* Not yet covered. Check for collisions. */ + + const float distSq1 = absSq( relativePosition1 ); + const float distSq2 = absSq( relativePosition2 ); + + const float radiusSq = sqr( _radius ); + + const float s = -(relativePosition1 * obstDir ); + const float distSqLine = absSq(relativePosition1 + s * obstDir ); + + Menge::Math::Line line; + + if (s < 0 && distSq1 <= radiusSq) { + /* Collision with left vertex. Ignore if non-convex. */ + if ( p0Convex ) { + line._point = Vector2(0.f,0.f); + line._direction = norm(Vector2(-relativePosition1.y(), relativePosition1.x())); + _orcaLines.push_back(line); + } + return; + } else if (s > LENGTH && distSq2 <= radiusSq) { + /* Collision with right vertex. Ignore if non-convex + * or if it will be taken care of by neighoring obstace */ + if ( ( obst->_nextObstacle == 0x0 ) || ( p1Convex && det(relativePosition2, obst->_nextObstacle->_unitDir) >= 0) ) { + line._point = Vector2(0.f,0.f); + line._direction = norm(Vector2(-relativePosition2.y(), relativePosition2.x())); + _orcaLines.push_back(line); + } + return; + } else if (s >= 0 && s < LENGTH && distSqLine <= radiusSq) { + /* Collision with obstacle segment. */ + line._point = Vector2(0.f,0.f); + line._direction = -obstDir; + _orcaLines.push_back(line); + return; + } + + /* + * No collision. + * Compute legs. When obliquely viewed, both legs can come from a single + * vertex. Legs extend cut-off line when nonconvex vertex. + */ + + Vector2 leftLegDirection, rightLegDirection; + + /*! + * These booleans short-cut the later code in which we make sure a leg direction does not + * cut into a "neighboring" obstacle. + * + * In the case where the agent is "obliquely viewing" the obstacle near the left or right edge, + * we end up testing one of the legs against obstacle 1 itself. However, by definition, we know that + * both legs lie outside of the obstacle. + */ + bool prevIsCurrent = false; + bool nextIsCurrent = false; + if (s < 0 && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that left vertex defines velocity obstacle. + */ + if ( !p0Convex ) { + /* Ignore obstacle. */ + return; + } + + nextIsCurrent = true; + + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * _radius, relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + rightLegDirection = Vector2(relativePosition1.x() * leg1 + relativePosition1.y() * _radius, -relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + } else if (s > LENGTH && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that right vertex defines velocity obstacle. + */ + if ( !p1Convex ) { + /* Ignore obstacle. */ + return; + } + + prevIsCurrent = true; + + const float leg2 = std::sqrt(distSq2 - radiusSq); + leftLegDirection = Vector2(relativePosition2.x() * leg2 - relativePosition2.y() * _radius, relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * _radius, -relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + } else { + /* Usual situation. */ + if ( p0Convex ) { + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * _radius, relativePosition1.x() * _radius + relativePosition1.y() * leg1) / distSq1; + } else { + /* Left vertex non-convex; left leg extends cut-off line. */ + leftLegDirection = -obstDir; + } + + if ( p1Convex ) { + const float leg2 = std::sqrt(distSq2 - radiusSq); + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * _radius, -relativePosition2.x() * _radius + relativePosition2.y() * leg2) / distSq2; + } else { + /* Right vertex non-convex; right leg extends cut-off line. */ + rightLegDirection = obstDir; + } + } + + /* + * Legs can never point into neighboring edge when convex vertex, + * take cutoff-line of neighboring edge instead. If velocity projected on + * "foreign" leg, no constraint is added. + */ + bool isLeftLegForeign = false; + bool isRightLegForeign = false; + + if ( !prevIsCurrent ) { + if ( leftNeighbor != 0x0 ) { + if ( p0Convex && det(leftLegDirection, -leftNeighbor->_unitDir) >= 0.0f) { + /* Left leg points into obstacle. */ + leftLegDirection = -leftNeighbor->_unitDir; + isLeftLegForeign = true; + } + } + } + + if ( !nextIsCurrent ) { + if ( rightNeighbor != 0x0 ) { + if ( p1Convex && det( rightLegDirection, rightNeighbor->_unitDir) <= 0.0f) { + /* Right leg points into obstacle. */ + rightLegDirection = rightNeighbor->_unitDir; + isRightLegForeign = true; + } + } + } + + /* Compute cut-off centers. */ + const Vector2 leftCutoff = invTau * ( prevIsCurrent ? relativePosition2 : relativePosition1 ); + const Vector2 rightCutoff = nextIsCurrent ? leftCutoff : ( invTau * relativePosition2 ); + const Vector2 cutoffVec = rightCutoff - leftCutoff; + const bool obstaclesSame = nextIsCurrent || prevIsCurrent; + + + /* Project current velocity on velocity obstacle. */ + /* Check if current velocity is projected on cutoff circles. */ + const float t = obstaclesSame ? 0.5f : ( (_vel - leftCutoff) * ( cutoffVec / absSq(cutoffVec) ) ); + const float tLeft = ((_vel - leftCutoff) * leftLegDirection); + const float tRight = ((_vel - rightCutoff) * rightLegDirection); + + if ((t < 0.0f && tLeft < 0.0f) || ( obstaclesSame && tLeft < 0.0f && tRight < 0.0f)) { + /* Project on left cut-off circle. */ + const Vector2 unitW = norm( _vel - leftCutoff ); + line._direction = Vector2( unitW.y(), -unitW.x() ); + line._point = leftCutoff + _radius * invTau * unitW; + _orcaLines.push_back(line); + return; + } else if (t > 1.0f && tRight < 0.0f) { + /* Project on right cut-off circle. */ + const Vector2 unitW = norm(_vel - rightCutoff); + line._direction = Vector2(unitW.y(), -unitW.x()); + line._point = rightCutoff + _radius * invTau * unitW; + _orcaLines.push_back(line); + return; + } + + /* + * Project on left leg, right leg, or cut-off line, whichever is closest + * to velocity. + */ + const float distSqCutoff = ((t < 0.0f || t > 1.0f || obstaclesSame) ? std::numeric_limits::infinity() : absSq(_vel - (leftCutoff + t * cutoffVec))); + const float distSqLeft = ((tLeft < 0.0f) ? std::numeric_limits::infinity() : absSq(_vel - (leftCutoff + tLeft * leftLegDirection))); + const float distSqRight = ((tRight < 0.0f) ? std::numeric_limits::infinity() : absSq(_vel - (rightCutoff + tRight * rightLegDirection))); + + if (distSqCutoff <= distSqLeft && distSqCutoff <= distSqRight) { + /* Project on cut-off line. */ + line._direction = -obstDir; + line._point = leftCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } else if (distSqLeft <= distSqRight) { + /* Project on left leg. */ + if ( !isLeftLegForeign) { + line._direction = leftLegDirection; + line._point = leftCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } + } else { + /* Project on right leg. */ + if ( !isRightLegForeign) { + line._direction = -rightLegDirection; + line._point = rightCutoff + _radius * invTau * Vector2(-line._direction.y(), line._direction.x()); + _orcaLines.push_back(line); + } + } + } + + /////////////////////////////////////////////////////////////////////// + + /* Compute the ORCA lines for the neighboring obstacles and agents */ + size_t Agent::computeORCALines( Vector2 & optVel, Vector2 & prefDir, float & prefSpeed ) { + _orcaLines.clear(); + + const float invTimeHorizonObst = 1.0f / _timeHorizonObst; + + /* Create obstacle ORCA lines. */ + for (size_t i = 0; i < _nearObstacles.size(); ++i) { + + const Menge::Agents::Obstacle* obst = _nearObstacles[i].obstacle; + const Vector2 P0 = obst->getP0(); + const Vector2 P1 = obst->getP1(); + const bool agtOnRight = leftOf( P0, P1, _pos ) < 0.f; + obstacleLine( i, invTimeHorizonObst, !agtOnRight && obst->_doubleSided ); + } + + const size_t numObstLines = _orcaLines.size(); + + const float invTimeHorizon = 1.0f / _timeHorizon; + + /* Create agent ORCA lines. */ + for (size_t i = 0; i < _nearAgents.size(); ++i) { + const Agent* const other = static_cast< const Agent *>( _nearAgents[i].agent ); + + const Vector2 relativePosition = other->_pos - _pos; + float rightOfWay = fabs( _priority - other->_priority ); + if ( rightOfWay > 1.f ) rightOfWay = 1.f; + + // Right of way-dependent calculations + Vector2 myVel = _vel; + Vector2 hisVel = other->_vel; + // this is my fraction of effort + float weight = 0.5f; + float const MAX_DEV = 0.1f; + float const MAX_DEV_SQD = MAX_DEV * MAX_DEV; + if ( _priority < other->_priority ) { + // his advantage + weight += 0.5f * rightOfWay; + hisVel = other->_velPref.getPreferredVel() * rightOfWay + ( 1.f - rightOfWay ) * other->_vel; + if ( absSq( hisVel - other->_vel ) > MAX_DEV_SQD ) { + hisVel = norm( other->_velPref.getPreferredVel() - other->_vel ) * MAX_DEV + other->_vel; + } + //if ( relativePosition * other->_velPref.getPreferredVel() < relativePosition * other->_vel ) { + // hisVel = other->_velPref.getPreferredVel() * rightOfWay + ( 1.f - rightOfWay ) * other->_vel; + //} + } else if ( _priority > other->_priority ) { + // my advantage + weight -= 0.5f * rightOfWay; + myVel = _velPref.getPreferredVel() * rightOfWay + ( 1.f - rightOfWay ) * _vel; + if ( absSq( myVel - _vel ) > MAX_DEV_SQD ) { + myVel = norm( _velPref.getPreferredVel() - _vel ) * MAX_DEV + _vel; + } + //if ( relativePosition * _velPref.getPreferredVel() > relativePosition * _vel ) { + // myVel = _velPref.getPreferredVel() * rightOfWay + ( 1.f - rightOfWay ) * _vel; + //} + } + + const Vector2 relativeVelocity = myVel - hisVel; + + const float distSq = absSq(relativePosition); + const float combinedRadius = _radius + other->_radius; + const float combinedRadiusSq = sqr(combinedRadius); + + Menge::Math::Line line; + Vector2 u; + + if (distSq > combinedRadiusSq) { + /* No collision. */ + const Vector2 w = relativeVelocity - invTimeHorizon * relativePosition; + /* Vector from cutoff center to relative velocity. */ + const float wLengthSq = absSq(w); + + const float dotProduct1 = w * relativePosition; + + if (dotProduct1 < 0.0f && sqr(dotProduct1) > combinedRadiusSq * wLengthSq) { + /* Project on cut-off circle. */ + const float wLength = std::sqrt(wLengthSq); + const Vector2 unitW = w / wLength; + + line._direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeHorizon - wLength) * unitW; + } else { + /* Project on legs. */ + const float leg = std::sqrt(distSq - combinedRadiusSq); + + if (det(relativePosition, w) > 0.0f) { + /* Project on left leg. */ + line._direction = Vector2(relativePosition.x() * leg - relativePosition.y() * combinedRadius, relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } else { + /* Project on right leg. */ + line._direction = -Vector2(relativePosition.x() * leg + relativePosition.y() * combinedRadius, -relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } + + const float dotProduct2 = relativeVelocity * line._direction; + + u = dotProduct2 * line._direction - relativeVelocity; + } + if ( u * relativePosition > 0 ) weight = 0.5f; + + line._point = myVel + weight * u; + } else { + /* Collision. Project on cut-off circle of time timeStep. */ + const float invTimeStep = 1.0f / Simulator::TIME_STEP; + + /* Vector from cutoff center to relative velocity. */ + const Vector2 w = relativeVelocity - invTimeStep * relativePosition; + + const float wLength = abs(w); + const Vector2 unitW = w / wLength; + + line._direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeStep - wLength) * unitW; + line._point = myVel + weight * u; + } + + _orcaLines.push_back(line); + } + + // Transform the lines + if ( _turningBias != 1.f ) { + prefSpeed = _velPref.getSpeed(); + optVel.set( prefSpeed, 0.f ); + // Transformation is dependent on prefSpeed being non-zero + if ( prefSpeed > Menge::EPS ) { + prefDir.set( _velPref.getPreferred() ); + Vector2 n( -prefDir.y(), prefDir.x() ); + // rotate and scale all of the lines + float turnInv = 1.f / _turningBias; + for ( size_t i = 0; i < _orcaLines.size(); ++i ) { + // Make sure I'm not perpendicular + if ( Simulator::COS_OBST_TURN < 1.f && // turning threshhold is bigger than zero degrees + _turningBias > 1.f && // only tilt if I'm seeking to magnify differences + i >= numObstLines && // don't perturb obstacles + det(_orcaLines[i]._direction, _orcaLines[i]._point - _velPref.getPreferredVel() ) > 0.0f && // preferred velocity is not feasible w.r.t. this obstacle + // This is a trick: det with the line direction, is dot product with normal + det( -_orcaLines[i]._direction, prefDir ) > Simulator::COS_OBST_TURN ) // angle between pref vel and line normal is less than 1/2 degree either way + { + // Compute the intersection with the circle of maximum velocity + float dotProduct = _orcaLines[i]._point * _orcaLines[i]._direction; + float discriminant = sqr(dotProduct) + sqr(_maxSpeed) - absSq(_orcaLines[i]._point); + if ( discriminant >= 0.f ) { // Intersects the circle of maximum speed + // I already know from the previous test that the preferred velocity lies on the infeasible side of the obstacle + // so, if there's no intersection, the whole circle must be infeasible. + // don't bother perturbing. + const float sqrtDiscriminant = std::sqrt(discriminant); + if ( _vel * _orcaLines[i]._direction > 0.f ) { + float t = -dotProduct + sqrtDiscriminant; + Vector2 p = _orcaLines[i]._point + t * _orcaLines[i]._direction; // new line point + // clockwise rotation + const Vector2 rx( Simulator::COS_OBST_TURN, Simulator::SIN_OBST_TURN ); + const Vector2 ry( -Simulator::SIN_OBST_TURN, Simulator::COS_OBST_TURN ); + float dx = det( prefDir, rx ); + float dy = det( prefDir, ry ); + _orcaLines[i]._direction.set( dx, dy ); + _orcaLines[i]._point.set( p ); + } else { + float t = -dotProduct - sqrtDiscriminant; + Vector2 p = _orcaLines[i]._point + t * _orcaLines[i]._direction; // new line point + // counter-clockwise rotation + const Vector2 rx( Simulator::COS_OBST_TURN, -Simulator::SIN_OBST_TURN ); + const Vector2 ry( Simulator::SIN_OBST_TURN, Simulator::COS_OBST_TURN ); + float dx = det( prefDir, rx ); + float dy = det( prefDir, ry ); + _orcaLines[i]._direction.set( dx, dy ); + _orcaLines[i]._point.set( p ); + } + } + } + + // rotate + float px = _orcaLines[i]._point * prefDir; + float py = _orcaLines[i]._point * n; + float dx = _orcaLines[i]._direction * prefDir; + float dy = _orcaLines[i]._direction * n ; + // scale + py *= turnInv; + dy *= turnInv; + // set + _orcaLines[i]._point.set( px, py ); + _orcaLines[i]._direction.set( norm( Vector2( dx, dy ) ) ); + } + } + } else { + optVel.set( _velPref.getPreferredVel() ); + } + + return numObstLines; + } + + /////////////////////////////////////////////////////////////////////// + + /* Search for the best new velocity. */ + void Agent::computeNewVelocity() { + adaptPreferredVelocity(); + + Vector2 optVel; + Vector2 prefDir; + float prefSpeed; + // Compute ORCA lines returns the optVel and prefSpeed as appropriate + const size_t numObstLines = computeORCALines( optVel, prefDir, prefSpeed ); + + size_t lineFail = linearProgram2(_orcaLines, _maxSpeed, optVel, false, _turningBias, _velNew); + + if (lineFail < _orcaLines.size()) { + linearProgram3(_orcaLines, numObstLines, lineFail, _maxSpeed, _turningBias, _velNew); + } + if ( _turningBias != 1.f && prefSpeed > Menge::EPS ) { + // Transform _velNew from affine space to real space + // Undo the scale + Vector2 vel( _velNew.x(), _velNew.y() * _turningBias ); + // Rotate it back + // Flip the y-value so I perform rotation in the other direction + // I'm multiplying v * R, where R is the matrix: + // + // R = [ prefDir' n' ] (i.e. concatenation of two column vectors + // + // I rotated INTO affine space using prefDir and n. To reverse the rotation + // I had to flip the signs of the upper right and lower left corners. That's + // What the negation of prefDir.y does. + prefDir.set( prefDir.x(), -prefDir.y() ); + Vector2 n( -prefDir.y(), prefDir.x() ); + float vx = vel * prefDir; + float vy = vel * n; + _velNew.set( vx, vy ); + + } + } + + /////////////////////////////////////////////////////////////////////// + + bool linearProgram1(const std::vector& lines, size_t lineNo, float radius, const Vector2& optVelocity, bool directionOpt, float turnBias, Vector2& result) { + // Despite turn the dot product is the same + // This is because the point got scaled by <1, 1/turn> and the dir got scaled by + // <1, turn>. So, pt.x * dir.x + pt.y * dir.y = pt.x * dir.x + pt.y /turn * dir.y * turn + // So, they are mathematically equivalent. + float dotProduct = lines[lineNo]._point * lines[lineNo]._direction; + float discriminant; + if ( turnBias != 1.f ) { + // test against transformed lines + Vector2 pt( lines[lineNo]._point.x(), lines[lineNo]._point.y() * turnBias ); + discriminant = sqr(dotProduct) + sqr(radius) - absSq( pt ); + + if (discriminant < 0.0f) { + /* Max speed circle fully invalidates line lineNo. */ + return false; + } + discriminant = sqr(dotProduct) + sqr(radius) - absSq(lines[lineNo]._point); + } else { + discriminant = sqr(dotProduct) + sqr(radius) - absSq(lines[lineNo]._point); + + if (discriminant < 0.0f) { + /* Max speed circle fully invalidates line lineNo. */ + return false; + } + } + + const float sqrtDiscriminant = std::sqrt(discriminant); + float tLeft = -dotProduct - sqrtDiscriminant; + float tRight = -dotProduct + sqrtDiscriminant; + + for (size_t i = 0; i < lineNo; ++i) { + const float denominator = det(lines[lineNo]._direction, lines[i]._direction); + const float numerator = det(lines[i]._direction, lines[lineNo]._point - lines[i]._point); + + if (std::fabs(denominator) <= Menge::EPS ) { + /* Lines lineNo and i are (almost) parallel. */ + if (numerator < 0.0f) { + return false; + } else { + continue; + } + } + + const float t = numerator / denominator; + + if (denominator >= 0.0f) { + /* Line i bounds line lineNo on the right. */ + tRight = std::min(tRight, t); + } else { + /* Line i bounds line lineNo on the left. */ + tLeft = std::max(tLeft, t); + } + + if (tLeft > tRight) { + return false; + } + } + + if (directionOpt) { + /* Optimize direction. */ + if (optVelocity * lines[lineNo]._direction > 0.0f) { + /* Take right extreme. */ + result = lines[lineNo]._point + tRight * lines[lineNo]._direction; + } else { + /* Take left extreme. */ + result = lines[lineNo]._point + tLeft * lines[lineNo]._direction; + } + } else { + /* Optimize closest point. */ + const float t = lines[lineNo]._direction * (optVelocity - lines[lineNo]._point); + + if (t < tLeft) { + result = lines[lineNo]._point + tLeft * lines[lineNo]._direction; + } else if (t > tRight) { + result = lines[lineNo]._point + tRight * lines[lineNo]._direction; + } else { + result = lines[lineNo]._point + t * lines[lineNo]._direction; + } + } + + return true; + } + + /////////////////////////////////////////////////////////////////////// + + size_t linearProgram2(const std::vector& lines, float radius, const Vector2& optVelocity, bool directionOpt, float turnBias, Vector2& result) { + if (directionOpt) { + /* + * Optimize direction. Note that the optimization velocity is of unit + * length in this case. + */ + result = optVelocity * radius; + } else if (absSq(optVelocity) > sqr(radius)) { + /* Optimize closest point and outside circle. */ + result = norm(optVelocity) * radius; + } else { + /* Optimize closest point and inside circle. */ + result = optVelocity; + } + + for (size_t i = 0; i < lines.size(); ++i) { + if (det(lines[i]._direction, lines[i]._point - result) > 0.0f) { + /* Result does not satisfy constraint i. Compute new optimal result. */ + const Vector2 tempResult = result; + if (!linearProgram1(lines, i, radius, optVelocity, directionOpt, turnBias, result)) { + result = tempResult; + return i; + } + } + } + return lines.size(); + } + + /////////////////////////////////////////////////////////////////////// + + void linearProgram3(const std::vector& lines, size_t numObstLines, size_t beginLine, float radius, float turnBias, Vector2& result) { + float distance = 0.0f; + + for (size_t i = beginLine; i < lines.size(); ++i) { + if (det(lines[i]._direction, lines[i]._point - result) > distance) { + /* Result does not satisfy constraint of line i. */ + std::vector projLines(lines.begin(), lines.begin() + numObstLines); + + for (size_t j = numObstLines; j < i; ++j) { + Menge::Math::Line line; + + float determinant = det(lines[i]._direction, lines[j]._direction); + + if (std::fabs(determinant) <= Menge::EPS ) { + /* Line i and line j are parallel. */ + if (lines[i]._direction * lines[j]._direction > 0.0f) { + /* Line i and line j point in the same direction. */ + continue; + } else { + /* Line i and line j point in opposite direction. */ + line._point = 0.5f * (lines[i]._point + lines[j]._point); + } + } else { + line._point = lines[i]._point + (det(lines[j]._direction, lines[i]._point - lines[j]._point) / determinant) * lines[i]._direction; + } + + line._direction = norm(lines[j]._direction - lines[i]._direction); + projLines.push_back(line); + } + + const Vector2 tempResult = result; + if (linearProgram2(projLines, radius, Vector2(-lines[i]._direction.y(), lines[i]._direction.x()), true, turnBias, result) < projLines.size()) { + /* This should in principle not happen. The result is by definition + * already in the feasible region of this linear program. If it fails, + * it is due to small floating point error, and the current result is + * kept. + */ + result = tempResult; + } + + distance = det(lines[i]._direction, lines[i]._point - result); + } + } + } +} // namespace PedVO diff --git a/src/Menge/MengeCore/PedVO/PedVOAgent.h b/src/Menge/MengeCore/PedVO/PedVOAgent.h new file mode 100644 index 00000000..e43cc3d8 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOAgent.h @@ -0,0 +1,256 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVOAgent.h + * @brief Contains the PedVOAgent class. + */ + +#ifndef __PEDVO_AGENT_H__ +#define __PEDVO_AGENT_H__ + +#include "BaseAgent.h" +#include "Math/Line.h" + +namespace PedVO { + /*! + * @brief Defines an agent in the simulation. + */ + class Agent : public Menge::Agents::BaseAgent { + public: + /*! + * @brief A variant of the copy constructor. + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief Based on the neighbors, computes the ORCA lines + * + * @returns The total number of obstacle lines + */ + size_t computeORCALines(); + + /*! + * @brief Based on the neighbors, computes the ORCA lines + * + * Based on turning, defines the optimization velocity + * (in the case of turning, it would be aligned with the + * x-axis with the same magnitude. It also returns the + * unit vector and magnitude of the preferred velocity + * @param optVel The vector2 containing, what will be used, for + * geometric optimization. + * @param prefDir The direction of the original preferred velocity + * This value is only set if the agent is turning. + * @param prefSpeed The magnitude of the original preferred velocity. + * This value is only set if the agent is turning. + * @returns The total number of obstacle lines + */ + size_t computeORCALines( Vector2 & optVel, Vector2 & prefDir, float & prefSpeed ); + + /*! + * @brief The set of ORCA constraints. + */ + std::vector _orcaLines; + + /*! + * @brief Sets the stride factor and stride buffer for + * estimating available space and determining viable speed. + * + * @param factor The stride factor. + * @param buffer The stride buffer. + */ + void setStrideParameters( float factor, float buffer ); + + /*! + * @brief Adapts the preferred velocity to conform to the local + * density. + * NOTE: This should ONLY be called after computing + * the baseline preferred velocity. + */ + void adaptPreferredVelocity(); + + /*! + * @brief Report the agent's stride constant. + * see BaseAgent::_strideConst. + * + * @returns The agent's stride constant. + */ + inline float getStrideConst() const { return _strideConst; } + + /*! + * @brief Report the agent's speed constant. + * see BaseAgent::_speedConst. + * + * @returns The agent's speed constant. + */ + inline float getSpeedConst() const { return _speedConst; } + + /*! + * @brief Controls if the agent respondes to density (true) or not (false). + */ + bool _denseAware; + + /*! + * @brief One of two derived constants for fundamental diagram compliance. + * This is a function of the stride factor and stride buffer + */ + float _strideConst; + + /*! + * @brief The second of two derived constants for fundamental diagram compliance. + * This is a function of the stride factor and stride buffer + */ + float _speedConst; + + /*! + * @brief The time horizon for inter-agent interactions. + */ + float _timeHorizon; + + /*! + * @brief The time horizon for agent-obstacle interactions. + */ + float _timeHorizonObst; + + /*! + * @brief Turning bias. + */ + float _turningBias; + + // DEFAULT VALUES FOR THE AGENT PARAMTERS + /*! + * @brief The default time horizon for inter-agent interactions. + */ + static const float TAU; + + /*! + * @brief The default time horizon for agent-obstacle interactions. + */ + static const float TAU_OBST; + + /*! + * @brief The default turn bias. + */ + static const float TURN_BIAS; + + /*! + * @brief The default stride factor value. + */ + static const float STRIDE_FACTOR; + + /*! + * @brief The default stride buffer value. + */ + static const float STRIDE_BUFFER; + + friend class Simulator; + + protected: + /*! + * @brief Constructs an ORCA line for the given obstacle + * under the assumption that the agent is on its right side. + * If appropriate, it adds the obstacle to the set of orca lines. + * + * @param obstNbrID The index of the near-by obstacle to test. + * @param invTau 1 / _timeHorizonObst - the inverse of the + * time horizon for obstacles. + * @param flip The agent is on the left side of this obstacle. + */ + void obstacleLine( size_t obstNbrID, const float invTau, bool flip ); + }; + + /*! + * @brief Solves a one-dimensional linear program on a specified line + * subject to linear constraints defined by lines and a circular + * constraint. + * + * @param lines Lines defining the linear constraints. + * @param lineNo The specified line constraint. + * @param radius The radius of the circular constraint. + * @param optVelocity The optimization velocity. + * @param directionOpt True if the direction should be optimized. + * @param turnBias The turn bias of the agent + * @param result A reference to the result of the linear program. + * @returns True if successful. + */ + bool linearProgram1(const std::vector& lines, size_t lineNo, + float radius, const Vector2& optVelocity, + bool directionOpt, float turnBias, Vector2& result); + + /*! + * @brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * + * @param lines Lines defining the linear constraints. + * @param radius The radius of the circular constraint. + * @param optVelocity The optimization velocity. + * @param directionOpt True if the direction should be optimized. + * @param turnBias The turn bias of the agent + * @param result A reference to the result of the linear program. + * @returns The number of the line it fails on, and the number of lines if successful. + */ + size_t linearProgram2(const std::vector& lines, float radius, + const Vector2& optVelocity, bool directionOpt, + float turnBias, + Vector2& result); + + /*! + * @brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * + * @param lines Lines defining the linear constraints. + * @param numObstLines Count of obstacle lines. + * @param beginLine The line on which the 2-d linear program failed. + * @param radius The radius of the circular constraint. + * @param turnBias The agent's turn bias. + * @param result A reference to the result of the linear program. + */ + void linearProgram3(const std::vector& lines, size_t numObstLines, size_t beginLine, + float radius, float turnBias, Vector2& result); +} // namespace PedVO +#endif diff --git a/src/Menge/MengeCore/PedVO/PedVOAgentContext.h b/src/Menge/MengeCore/PedVO/PedVOAgentContext.h new file mode 100644 index 00000000..13c16e29 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOAgentContext.h @@ -0,0 +1,173 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVOAgentContext.h + * @brief A basic context for interacting with and displaying + * PedVO agent parameters + */ + +#ifndef __PEDVO_AGENT_CONTEXT_H__ +#define __PEDVO_AGENT_CONTEXT_H__ + +#include "../Orca/ORCATypeAgentContext.h" +#include "PedVOAgent.h" + +namespace PedVO { + /*! + * @brief Declaration of ORCA-type agent context for PedVO agents. + */ + typedef ORCATypeAgentContext< Agent > PedVOAgentContext; +} + +//////////////////////////////////////////////////////////////// +// Implementation of PedVOAgentContext +//////////////////////////////////////////////////////////////// + +// Specialization +template <> +std::string ORCATypeAgentContext< PedVO::Agent >::contextName() const { return "PedVO"; } + +//////////////////////////////////////////////////////////////// + +/*! + * @brief Draw the optimized velocity for the current set of orca lines + * + * @param agent A pointer to the agent for which the velocity is drawn + * computeNewVelocity will be called on the agent + */ +template<> +inline void ORCATypeAgentContext< PedVO::Agent >::drawOptVelocity( PedVO::Agent * agent ) const { + // Draw the optimized velocity (transformed and untransformed + agent->computeNewVelocity(); + glPushAttrib( GL_POINT_BIT ); + glPointSize( 3.f ); + // NORMAL space + glColor3f( 0.2f, 0.2f, 1.f ); + glBegin( GL_POINTS ); + glVertex3f( agent->_pos.x() + agent->_velNew.x(), Y, agent->_pos.y() + agent->_velNew.y() ); + glEnd(); + writeTextRadially( " v_new ", agent->_pos + agent->_velNew, agent->_velNew, true ); + + Vector2 prefDir( agent->_velPref.getPreferred() ); + Vector2 n( -prefDir.y(), prefDir.x() ); + float vx = agent->_velNew * prefDir; + float vy = agent->_velNew * n; + vy /= agent->_turningBias; + glColor3f( 1.f, 0.1f, 1.f ); + glBegin( GL_POINTS ); + glVertex3f( agent->_pos.x() + vx, Y, agent->_pos.y() + vy ); + glEnd(); + Vector2 vn( vx, vy ); + writeTextRadially( " v_new^x", agent->_pos + vn, vn, true ); + glPopAttrib(); +} + +//////////////////////////////////////////////////////////////// + +/*! + * @brief Draws the given ORCA line for the given agent + * + * @param agent A pointer to the agent to whom this line applies + * @param line The actual line + * @param isAgent A boolean reporting if the orca line comes from an agent. + * true --> agent, false --> obstacle + */ +template<> +void ORCATypeAgentContext< PedVO::Agent >::drawORCALine( const PedVO::Agent * agent, const Menge::Math::Line & line, bool isAgent ) const { + if ( agent->_turningBias != 1.f ) { + // Transform line into new line + Menge::Math::Line lEuclid; // the line transformed, fully, back into Euclidian space + lEuclid._point = line._point; + lEuclid._direction = line._direction; + Menge::Math::Line lAffine; // the line (with scale) rotated back into Euclidian + float prefSpeed = agent->_velPref.getSpeed(); + // Transformation is dependent on prefSpeed being non-zero + bool rotated = false; + if ( prefSpeed > Menge::EPS ) { + Vector2 prefDir( agent->_velPref.getPreferred() ); + Vector2 n( prefDir.y(), prefDir.x() ); + // rotate and scale all of the lines + float turnInv = 1.f / agent->_turningBias; + + // scale + Vector2 p( line._point.x(), line._point.y() * agent->_turningBias ); + Vector2 d ( line._direction.x(), line._direction.y() * agent->_turningBias ); + // rotate + float px = p * prefDir; + float py = p * n; + float dx = d * prefDir; + float dy = d * n ; + // set + lEuclid._point.set( px, py ); + lEuclid._direction.set( dx, dy ); + + px = line._point * prefDir; + py = line._point * n; + dx = line._direction * prefDir; + dy = line._direction * n ; + lAffine._point.set( px, py ); + lAffine._direction.set( dx, dy ); + rotated = true; + } + if ( rotated ) { + if ( isAgent ) { + drawHalfPlane( lAffine, agent->_pos, 1.f, 0.5f, 0.f, Y ); + if ( ! _showOrcaLines ) drawHalfPlane( lEuclid, agent->_pos, 1.f, 0.f, 0.f, Y ); + } else { + drawHalfPlane( lAffine, agent->_pos, 0.5f, 0.5f, 0.5f, Y ); + if ( ! _showOrcaLines ) drawHalfPlane( lEuclid, agent->_pos, 0.75f, 0.75f, 0.75f, Y ); + } + } else { + if ( isAgent ) { + drawHalfPlane( lEuclid, agent->_pos, 1.f, 0.f, 0.f, Y ); + } else { + drawHalfPlane( lEuclid, agent->_pos, 0.75f, 0.75f, 0.75f, Y ); + } + } + + } else { + if ( isAgent ) { + drawHalfPlane( line, agent->_pos, 1.f, 0.f, 0.f, Y ); + } else { + drawHalfPlane( line, agent->_pos, 0.75f, 0.75f, 0.75f, Y ); + } + } +} + +#endif // __PEDVO_AGENT_CONTEXT_H__ diff --git a/src/Menge/MengeCore/PedVO/PedVODBEntry.cpp b/src/Menge/MengeCore/PedVO/PedVODBEntry.cpp new file mode 100644 index 00000000..7fe609c4 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVODBEntry.cpp @@ -0,0 +1,91 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PedVODBEntry.h" +#include "SimulatorDB.h" +#include "PedVOAgentContext.h" +#include "PedVODBEntry.h" +#include "PedVOInitializer.h" +#include "PedVOSimulator.h" +#include "SimSystem.h" +#include "BaseAgentContext.h" + +namespace PedVO { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of PedVO::DBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Simulator based on Pedestrian Velocity Obstacle model"; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on Pedestrian Velocity Obstacle model\n" + "\tUnderlying collision avoidance is based on van den Berg's 2009\n" + "\tORCA paper. The model has been extended to include density-\n" + "\tdependent behavior and right of way"; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "PedVO"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::BaseAgentContext * DBEntry::contextFromSystem( Menge::SimSystem * simSystem ) { + return new PedVOAgentContext( simSystem->getVisAgents(), (unsigned int)simSystem->getAgentCount() ); + } + + ///////////////////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// +} // namespace PedVO \ No newline at end of file diff --git a/src/Menge/MengeCore/PedVO/PedVODBEntry.h b/src/Menge/MengeCore/PedVO/PedVODBEntry.h new file mode 100644 index 00000000..00d3ff50 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVODBEntry.h @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVODBEntry.h + * @brief The simulator database entry for the PedVO pedestrian model. + */ + +#ifndef __PEDVO_DB_ENTRY_H__ +#define __PEDVO_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "PedVO.h" + +namespace PedVO { + /*! + * @brief The simulator database entry for the PedVO simulator. + */ + class DBEntry : public Menge::SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "pedvo"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Menge::Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Menge::Agents::AgentInitializer * getAgentInitalizer() const; + + protected: + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * If the provided system is not, in fact, a pointer to a SimSystem for the + * appropriate simulator type, this function will report failure. Furthermore, + * the default implementation is to return a BaseAgentContext. If the + * simulator comes with a novel context, this function should be overridden + * in the derived SimulatorDBEntry. + * + * @param simSystem The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntry::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. If the system is of + * the wrong type (or if there is any other problem), NULL is returned. + */ + virtual Menge::BaseAgentContext * contextFromSystem( Menge::SimSystem * simSystem ); + }; +} // namespace PedVO + +#endif // __PEDVO_DB_ENTRY_H__ diff --git a/src/Menge/MengeCore/PedVO/PedVOInitializer.cpp b/src/Menge/MengeCore/PedVO/PedVOInitializer.cpp new file mode 100644 index 00000000..85d2a0a8 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOInitializer.cpp @@ -0,0 +1,182 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PedVOInitializer.h" +#include "PedVOAgent.h" +#include "Math/RandGenerator.h" + +using namespace Menge::Math; + +namespace PedVO { + + //////////////////////////////////////////////////////////////// + // Implementation of ORCA::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float TAU = 2.5f; ///< The default time horizon for predicting agent collisions + const float TAU_OBST = 0.15f; ///< The default time horizon for predicting obstacle collisions + const float TURNING_BIAS = 1.f; ///< The default turn bias + const float STRIDE_FACTOR = 1.57f; ///< The default stride factor + const float STRIDE_BUFFER = 0.9f; ///< The default stride buffer + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Menge::Agents::AgentInitializer() { + _timeHorizon = new ConstFloatGenerator( TAU ); + _timeHorizonObst = new ConstFloatGenerator( TAU_OBST ); + _turningBias = new ConstFloatGenerator( TURNING_BIAS ); + _strideFactor = new ConstFloatGenerator( STRIDE_FACTOR ); + _strideBuffer = new ConstFloatGenerator( STRIDE_BUFFER ); + _denseAware = true; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) : Menge::Agents::AgentInitializer(init) { + _timeHorizon = init._timeHorizon->copy(); + _timeHorizonObst = init._timeHorizonObst->copy(); + _turningBias = init._turningBias->copy(); + _strideFactor = init._strideFactor->copy(); + _strideBuffer = init._strideBuffer->copy(); + _denseAware = init._denseAware; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _timeHorizon; + delete _timeHorizonObst; + delete _turningBias; + delete _strideFactor; + delete _strideBuffer; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Menge::Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_timeHorizon = _timeHorizon->getValue(); + a->_timeHorizonObst = _timeHorizonObst->getValue(); + a->_turningBias = _turningBias->getValue(); + float factor = _strideFactor->getValue(); + float buffer = _strideBuffer->getValue(); + a->setStrideParameters( factor, buffer ); + a->_denseAware = _denseAware; + + return Menge::Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "PedVO" ) || Menge::Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + Menge::Agents::AgentInitializer::ParseResult result = IGNORED; + if ( paramName == "tau" ) { + result = constFloatGenerator( _timeHorizon, value ); + } else if ( paramName == "tauObst" ) { + result = constFloatGenerator( _timeHorizonObst, value ); + } else if ( paramName == "turningBias" ) { + result = constFloatGenerator( _turningBias, value ); + } else if ( paramName == "factor" ) { + result = constFloatGenerator( _strideFactor, value ); + } else if ( paramName == "buffer" ) { + result = constFloatGenerator( _strideBuffer, value ); + } else if ( paramName == "density_aware" ) { + _denseAware = atoi( value.c_str() ) != 0; + } + + if ( result == FAILURE ) { + Menge::logger << Menge::Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Menge::Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + Menge::Agents::AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + Menge::Agents::AgentInitializer::ParseResult result = IGNORED; + if ( propName == "tau" ) { + result = getFloatGenerator( _timeHorizon, node ); + } else if ( propName == "tauObst" ) { + result = getFloatGenerator( _timeHorizonObst, node ); + } else if ( propName == "turningBias" ) { + result = getFloatGenerator( _turningBias, node ); + } else if ( propName == "factor" ) { + result = getFloatGenerator( _strideFactor, node ); + } else if ( propName == "buffer" ) { + result = getFloatGenerator( _strideBuffer, node ); + } + + if ( result == FAILURE ) { + Menge::logger << Menge::Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Menge::Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _timeHorizon ) delete _timeHorizon; + _timeHorizon = new ConstFloatGenerator( TAU ); + if ( _timeHorizonObst ) delete _timeHorizonObst; + _timeHorizonObst = new ConstFloatGenerator( TAU_OBST ); + if ( _strideFactor ) delete _strideFactor; + _strideFactor = new ConstFloatGenerator( STRIDE_FACTOR ); + if ( _strideBuffer ) delete _strideBuffer; + _strideBuffer = new ConstFloatGenerator( STRIDE_BUFFER ); + _denseAware = true; + + Menge::Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace ORCA diff --git a/src/Menge/MengeCore/PedVO/PedVOInitializer.h b/src/Menge/MengeCore/PedVO/PedVOInitializer.h new file mode 100644 index 00000000..74e59400 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOInitializer.h @@ -0,0 +1,193 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVOInitializer.h + * @brief The AgentInitializer for the PedVO simulator. + */ +#ifndef __PEDVO_INITIALIZER_H__ +#define __PEDVO_INITIALIZER_H__ + +#include "AgentInitializer.h" + +namespace PedVO { + /*! + * @brief Class which determines the agent properties for each new PedVO agent. + */ + class AgentInitializer : public Menge::Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The AgentInitializer to copy all values + * from. + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Menge::Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual Menge::Agents::AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `` + * parameter set. + * + * @param tagName The tag to test for relevancy. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Menge::Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given tag. + * + * As a pre-condition to this function, the XML node contains a + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual Menge::Agents::AgentInitializer::ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief Controls if the agent respondes to density (true) or not (false). + */ + bool _denseAware; + + /*! + * @brief The stride factor of the agent. + */ + FloatGenerator * _strideFactor; + + /*! + * @brief The stride factor of the agent. + */ + FloatGenerator * _strideBuffer; + + /*! + * @brief The time horizon for predicting agent collisions + */ + FloatGenerator * _timeHorizon; + + /*! + * @brief The time horizon for predicting obstacle collisions + */ + FloatGenerator * _timeHorizonObst; + + /*! + * @brief The turning bias. + */ + FloatGenerator * _turningBias; + }; +} // namespace PedVO + + +#endif // __PEDVO_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PedVO/PedVOSimSystem.h b/src/Menge/MengeCore/PedVO/PedVOSimSystem.h new file mode 100644 index 00000000..0288f74f --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOSimSystem.h @@ -0,0 +1,77 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVOSimSystem.h + * @brief Specialization of the SimSystem for PedVO agents + * + * This serves as an example on how to do something of this type. + * In this case, a ground plane is added when visualizing PedVO + * simulations. + */ + +#ifndef __PED_VO_SIM_SYSTEM_H__ +#define __PED_VO_SIM_SYSTEM_H__ + +// Specialization of SimSystem for PedVO - a simple illustration. +#include "SimSystem.h" +// PedVO +#include "PedVO.h" +// Scene graph +#include "GLGroundPlane.h" + +/*! + * @brief Specialization of the SimSystem for Agents::PedVO. + * + * This version adds an additional ground plane. + * + * @param scene The scene which receives nodes for drawing agents. + */ +template<> +void SimSystem< PedVO::Simulator, PedVO::Agent >::populateScene( Menge::SceneGraph::GLScene * scene ) { + assert( _sim != 0x0 && "Can't add SimSystem to scene when no simulator is connected" ); + + addAgentsToScene( scene ); + addObstacleToScene( scene ); + + Menge::SceneGraph::GLGroundPlane * plane = new Menge::SceneGraph::GLGroundPlane( 100.f, 100.f, 5.f, 4 ); + plane->setLineColor( 1.f, 1.f, 1.f ); + scene->addNode( plane ); +} + +#endif // __PED_VO_SIM_SYSTEM_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PedVO/PedVOSimulator.cpp b/src/Menge/MengeCore/PedVO/PedVOSimulator.cpp new file mode 100644 index 00000000..8d43dc45 --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOSimulator.cpp @@ -0,0 +1,51 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PedVOSimulator.h" +#include "PedVOAgent.h" +#include "Math/consts.h" + +namespace PedVO { + //////////////////////////////////////////////////////////////// + // Implementation of PedVO::Simulator + //////////////////////////////////////////////////////////////// + + float Simulator::COS_OBST_TURN = 1.f; + float Simulator::SIN_OBST_TURN = 0.f; + +} // namespace PedVO diff --git a/src/Menge/MengeCore/PedVO/PedVOSimulator.h b/src/Menge/MengeCore/PedVO/PedVOSimulator.h new file mode 100644 index 00000000..d5dcb25e --- /dev/null +++ b/src/Menge/MengeCore/PedVO/PedVOSimulator.h @@ -0,0 +1,88 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PedVOSimulator.h + * @brief Contains the ORCA::Simulator class. + */ + +#ifndef __PEDVO_SIMULATOR_H__ +#define __PEDVO_SIMULATOR_H__ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "PedVOAgent.h" + +/*! + * @namespace PedVO + * @brief Contains the specification of the pedestrian model + * based on Pedestrian Velocity Obstacles. + */ +namespace PedVO { + /*! + * @brief Defines the simulator operating on ORCA::Agent. + */ + class Simulator : public Menge::Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator() : Menge::Agents::SimulatorBase< Agent >() {} + + protected: + friend class Agent; + + /*! + * @brief The cosine of the threshold angle beyond which the constraints + * should be tilted. If the dot product between the preferred + * *direction* and the constraint's normal is greater than or + * equal then this threshhold, the obstacle is tilted. + * + * This is also used to perform the minimum rotation. + */ + static float COS_OBST_TURN; + + /*! + * @brief The sine of the threshold angle beyond which the constraints + * should be tilted. Used in conjunction with COS_OBST_TURN to + * perform the minmum tilt. + */ + static float SIN_OBST_TURN; + }; +} // namespace PedVO +#endif diff --git a/src/Menge/MengeCore/PluginEngine/Attribute.cpp b/src/Menge/MengeCore/PluginEngine/Attribute.cpp new file mode 100644 index 00000000..532c8ab8 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/Attribute.cpp @@ -0,0 +1,234 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Attribute.h" +#include "Logger.h" +#include "Utils.h" +#include "os.h" +#include "Math/RandGenerator.h" +#include "tinyxml.h" +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Attribute + ///////////////////////////////////////////////////////////////////// + + void Attribute::clear() { + _valid = false; + if ( !_required ) { + _valid = true; + setDefault(); + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of StringAttribute + ///////////////////////////////////////////////////////////////////// + + bool StringAttribute::extract( TiXmlElement * node ) { + const char * val = node->Attribute( _name.c_str() ); + if ( val ) { + _value = val; + } else if ( _required ) { + // Didn't get a value and it is required + logger << Logger::ERR_MSG << "Expecting a missing string attribute (" << _name << ") on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing string attribute (" << _name << ") on line " << node->Row() << ". Using default value: " << _default << "."; + } + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of IntAttribute + ///////////////////////////////////////////////////////////////////// + + bool IntAttribute::extract( TiXmlElement * node ) { + int i; + if ( node->Attribute( _name, &i ) ) { + _value = i; + } else if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing int attribute (" << _name << ") on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing int attribute (" << _name << ") on line " << node->Row() << ". Using default value: " << _default << "."; + } + return true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of FloatAttribute + ///////////////////////////////////////////////////////////////////// + + bool FloatAttribute::extract( TiXmlElement * node ) { + double d; + if ( node->Attribute( _name, &d ) ) { + _value = static_cast< float >( d ); + } else if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing float attribute (" << _name << ") on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing float attribute (" << _name << ") on line " << node->Row() << ". Using default value: " << _default << "."; + } + return true; + } + + //////////////////////////////////////////////////////////////////// + // Implementation of BoolAttribute + ///////////////////////////////////////////////////////////////////// + + bool BoolAttribute::extract( TiXmlElement * node ) { + int i; + if ( node->Attribute( _name, &i ) ) { + _value = i != 0; + } else if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing boolean attribute (" << _name << ") on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing boolean attribute (" << _name << ") on line " << node->Row() << ". Using default value: " << _default << "."; + } + return true; + } + + //////////////////////////////////////////////////////////////////// + // Implementation of SizeTAttribute + ///////////////////////////////////////////////////////////////////// + + bool SizeTAttribute::extract( TiXmlElement * node ) { + int i; + if ( node->Attribute( _name, &i ) ) { + if ( i >= 0 ) { + _value = static_cast< size_t >( i ); + } else { + logger << Logger::ERR_MSG << "Expecting a size_t attribute (" << _name << ") on line " << node->Row() << ". Found a negative number!"; + return false; + } + } else if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing size_t attribute (" << _name << ") on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing size_t attribute (" << _name << ") on line " << node->Row() << ". Using default value: " << _default << "."; + } + return true; + } + + //////////////////////////////////////////////////////////////////// + // Implementation of FloatDistributionAttribute + ///////////////////////////////////////////////////////////////////// + + FloatDistributionAttribute::~FloatDistributionAttribute() { + if ( _generator ) { + delete _generator; + } + } + + ///////////////////////////////////////////////////////////////////// + + bool FloatDistributionAttribute::extract( TiXmlElement * node ) { + if ( _generator ) delete _generator; + _generator = createFloatGenerator( node, _scale, _name ); + if ( _generator == 0x0 ) { + if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing float distribution specification on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing float distribution specification on line " << node->Row() << ". Using a const distribution with value: " << _default << "."; + _generator = new ConstFloatGenerator( _default ); + } + } + return true; + } + + //////////////////////////////////////////////////////////////////// + // Implementation of Vec2DDistributionAttribute + ///////////////////////////////////////////////////////////////////// + + Vec2DDistributionAttribute::~Vec2DDistributionAttribute() { + if ( _generator ) { + delete _generator; + } + } + + ///////////////////////////////////////////////////////////////////// + + bool Vec2DDistributionAttribute::extract( TiXmlElement * node ) { + if ( _generator ) delete _generator; + _generator = create2DGenerator( node, _scale ); + if ( _generator == 0x0 ) { + if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing 2D vector distribution specification on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing 2D vector distribution specification on line " << node->Row() << ". Using a const distribution with value: " << _default << "."; + _generator = new Const2DGenerator( _default ); + } + } + return true; + } + + //////////////////////////////////////////////////////////////////// + // Implementation of IntDistributionAttribute + ///////////////////////////////////////////////////////////////////// + + IntDistributionAttribute::~IntDistributionAttribute() { + if ( _generator ) { + delete _generator; + } + } + + ///////////////////////////////////////////////////////////////////// + + bool IntDistributionAttribute::extract( TiXmlElement * node ) { + if ( _generator ) delete _generator; + _generator = createIntGenerator( node, _name ); + if ( _generator == 0x0 ) { + if ( _required ) { + logger << Logger::ERR_MSG << "Expecting a missing int distribution specification on line " << node->Row() << "."; + return false; + } else { + logger << Logger::WARN_MSG << "Expecting a missing int distribution specification on line " << node->Row() << ". Using a const distribution with value: " << _default << "."; + _generator = new ConstIntGenerator( _default ); + } + } + return true; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/Attribute.h b/src/Menge/MengeCore/PluginEngine/Attribute.h new file mode 100644 index 00000000..c4f7e985 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/Attribute.h @@ -0,0 +1,726 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Attribute.h + * @brief Defines a single attribute of an element. + */ + +#ifndef __ATTRIBUTE_H__ +#define __ATTRIBUTE_H__ + +#include "CoreConfig.h" +#include +#include "MengeException.h" +#include "Math/Vector2.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + namespace Math { + class FloatGenerator; + class IntGenerator; + class Vec2DGenerator; + } + using namespace Math; + + /*! + * @brief Exception class for attribute definition problems + * (i.e., using the wrong type of attribute for the wrong + * data-type). + */ + class MENGE_API AttributeDefinitionException : public virtual Menge::MengeException { + public: + /*! + * @brief Default constructor. + */ + AttributeDefinitionException() : Menge::MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AttributeDefinitionException( const std::string & s ): Menge::MengeException(s) {} + }; + + /*! + * @brief The fatal attribute definition exception. + */ + class MENGE_API AttributeDefinitionFatalException : public AttributeDefinitionException, public Menge::MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + AttributeDefinitionFatalException() : Menge::MengeException(), AttributeDefinitionException(), Menge::MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + AttributeDefinitionFatalException( const std::string & s ): Menge::MengeException(s), AttributeDefinitionException(), Menge::MengeFatalException() {} + }; + + /*! + * @brief An element attribute. + * + * This serves as a simple mechanism to configure XML parsing for elements who only + * require simple xml-parameter-style arguments. See AttributeSet for proper user. + * This is the entity responsible for parsing the XML and extracting the value specified. + * + * The Attribute also stores the parsed value and reports on its own "validity". + * The validity of an Attribute is based on whether it is set to be "required" + * (i.e., the user *must* explicitly specify a value). If a required attribute is + * not defined in the XML, then it is invalid. + */ + class MENGE_API Attribute { + public: + /*! + * @brief Constructor + * + * @param name The attribute name - used in parsing XML attributes. + * @param required Whether or not the attribute is required (true) + * or not (false). + */ + Attribute( const std::string & name, bool required ): _name(name), _required(required) {} + + /*! + * @brief Destructor + */ + virtual ~Attribute(){} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ) = 0; + + /*! + * @brief Returns a const reference to the name of the attribute. + * + * @returns The name of the attribute. + */ + inline const std::string & getName() const { return _name; } + + /*! + * @brief Reports if this attribute is required to be specified. + * + * @returns True if this attribute must be specified, false otherwise. + */ + inline bool isRequired() const { return _required; } + + /*! + * @brief Reports if the attribute is valid. + * + * @returns True if the attribute is properly initialized, false otherwise. + */ + inline bool isValid() const { return _valid; } + + /*! + * @brief Prepares the attribute for a parse attempt. + */ + void clear(); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() = 0; + + /*! + * @brief Retrieve the parsed int value. + * + * If the type of this attribute is not an int, an exception will be thrown. + * + * @returns The int value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual int getInt() { throw AttributeDefinitionException("This Attribute can't provide an int value."); } + + /*! + * @brief Retrieve the parsed boolean value. + * + * If the type of this attribute is not a bool, an exception will be thrown. + * + * @returns The boolean value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual bool getBool() { throw AttributeDefinitionException("This Attribute can't provide a boolean value."); } + + /*! + * @brief Retrieve the parsed float value. + * + * If the type of this attribute is not a float, an exception will be thrown. + * + * @returns The float value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual float getFloat() { throw AttributeDefinitionException("This Attribute can't provide anfloat value."); } + + /*! + * @brief Retrieve the parsed string value. + * + * If the type of this attribute is not a string, an exception will be thrown. + * + * @returns The string value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual std::string getString() { throw AttributeDefinitionException("This Attribute can't provide a string value."); } + + /*! + * @brief Retrieve the parsed size_t value. + * + * If the type of this attribute is not a size_t, an exception will be thrown. + * + * @returns The size_t value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual size_t getSizeT() { throw AttributeDefinitionException("This Attribute can't provide a size_t value."); } + + /*! + * @brief Retrieve the parsed float generator. + * + * If the type of this attribute is not a float generator, an exception will be thrown. + * + * @returns A pointer to a float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual FloatGenerator * getFloatGenerator(){ throw AttributeDefinitionException("This Attribute can't provide a float generator."); } + + /*! + * @brief Retrieve the parsed 2D float generator. + * + * @returns A pointer to a 2D float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual Vec2DGenerator * getVec2DGenerator(){ throw AttributeDefinitionException("This Attribute can't provide a 2D float generator."); } + + /*! + * @brief Retrieve the parsed int generator. + * + * If the type of this attribute is not an int generator, an exception will be thrown. + * + * @returns A pointer to a float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual IntGenerator * getIntGenerator(){ throw AttributeDefinitionException("This Attribute can't provide an int generator."); } + + protected: + /*! + * @brief The name of the xml attribute. + */ + std::string _name; + + /*! + * @brief Determines if the XML *must* specify this attribute. + */ + bool _required; + + /*! + * @brief Reports if the attribute is valid. An attribute is always + * valid if it is not required. Otherwise, it is only valid if + * it was able to be initialized from the XML. + */ + bool _valid; + + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a string-type value. + */ + class MENGE_API StringAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + */ + StringAttribute( const std::string & name, bool required, const std::string & defValue="" ): Attribute(name,required), _default(defValue) {} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _value = _default; } + + /*! + * @brief Retrieve the parsed string value. + * + * @returns The string value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual std::string getString() { return _value; } + + protected: + /*! + * @brief The default string value. Meaningless if _required is true. + */ + std::string _default; + + /*! + * @brief The parsed attribute value. + */ + std::string _value; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a int-type value. + */ + class MENGE_API IntAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + */ + IntAttribute( const std::string & name, bool required, int defValue ): Attribute(name,required), _default(defValue) {} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _value = _default; } + + /*! + * @brief Retrieve the parsed int value. + * + * @returns The int value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual int getInt() { return _value; } + + protected: + /*! + * @brief The default int value. Meaningless if _required is true. + */ + int _default; + + /*! + * @brief The parsed attribute value. + */ + int _value; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a float-type value. + */ + class MENGE_API FloatAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + */ + FloatAttribute( const std::string & name, bool required, float defValue ): Attribute(name,required), _default(defValue) {} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _value = _default; } + + /*! + * @brief Retrieve the parsed float value. + * + * @returns The float value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual float getFloat() { return _value; } + protected: + /*! + * @brief The default float value. Meaningless if _required is true. + */ + float _default; + + /*! + * @brief The parsed attribute value. + */ + float _value; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a boolean-type value. + */ + class MENGE_API BoolAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + */ + BoolAttribute( const std::string & name, bool required, bool defValue ): Attribute(name,required), _default(defValue) {} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _value = _default; } + + /*! + * @brief Retrieve the parsed boolean value. + * + * @returns The boolean value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual bool getBool() { return _value; } + + protected: + /*! + * @brief The default bool value. Meaningless if _required is true. + */ + bool _default; + + /*! + * @brief The parsed attribute value. + */ + bool _value; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a size_t-type value. + */ + class MENGE_API SizeTAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + */ + SizeTAttribute( const std::string & name, bool required, size_t defValue ): Attribute(name,required), _default(defValue) {} + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _value = _default; } + + /*! + * @brief Retrieve the parsed size_t value. + * + * @returns The size_t value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual size_t getSizeT() { return _value; } + + protected: + /*! + * @brief The default bool value. Meaningless if _required is true. + */ + size_t _default; + + /*! + * @brief The parsed attribute value. + */ + size_t _value; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a float distribution value. + */ + class MENGE_API FloatDistributionAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name - in this case, interpreted as the + * the prefix for the distribution values. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This will be interpreted as a const distribution. + * @param scale The optional scale value for this float distribution. + */ + FloatDistributionAttribute( const std::string & name, bool required, float defValue, float scale=1.f ): Attribute(name,required), _default(defValue), _scale(scale), _generator(0x0) {} + + /*! + * @brief Destructor + */ + virtual ~FloatDistributionAttribute(); + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _generator = 0x0; } + + /*! + * @brief Retrieve the parsed float generator. + * + * @returns A pointer to a float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual FloatGenerator * getFloatGenerator(){ FloatGenerator * val = _generator; _generator=0x0; return val; } + + protected: + /*! + * @brief The default float value. Meaningless if _required is true. + */ + float _default; + + /*! + * @brief Scale value. Useful for converting units at parse time (i.e. from + * degrees to radians. + */ + float _scale; + + /*! + * @brief The parsed generator. + */ + FloatGenerator * _generator; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with a 2D float distribution value. + */ + class MENGE_API Vec2DDistributionAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * The 2D Vector generator does not accept an optional prefix like the float and int + * distributions. + * + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This will be interpreted as a const distribution. + * @param scale The optional scale value for this float distribution. + */ + Vec2DDistributionAttribute( bool required, const Vector2 & defValue, float scale=1.f ): Attribute("",required), _default(defValue), _scale(scale), _generator(0x0) {} + + /*! + * @brief Destructor + */ + virtual ~Vec2DDistributionAttribute(); + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _generator = 0x0; } + + /*! + * @brief Retrieve the parsed 2D float generator. + * + * @returns A pointer to a 2D float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual Vec2DGenerator * getVec2DGenerator(){ Vec2DGenerator * val = _generator; _generator=0x0; return val; } + + protected: + /*! + * @brief The default float value. Meaningless if _required is true. + */ + Vector2 _default; + + /*! + * @brief Scale value. Useful for converting units at parse time (i.e. from + * degrees to radians. + */ + float _scale; + + /*! + * @brief The parsed generator. + */ + Vec2DGenerator * _generator; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class which specifies an xml attribute with an int distribution value. + */ + class MENGE_API IntDistributionAttribute : public Attribute { + public: + /*! + * @brief Constructor. + * + * @param name The attribute name - in this case, interpreted as the + * the prefix for the distribution values. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This will be interpreted as a const distribution. + */ + IntDistributionAttribute( const std::string & name, bool required, int defValue ): Attribute(name,required), _default(defValue), _generator(0x0) {} + + /*! + * @brief Destructor + */ + virtual ~IntDistributionAttribute(); + + /*! + * @brief Extracts the values for this attribute from the xml node. + * + * This is the main parsing work. It must be performed by each attribute sub-class. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + virtual bool extract( TiXmlElement * node ); + + /*! + * @brief If defined, sets the default value for the attribute. + */ + virtual void setDefault() { _generator = 0x0; } + + /*! + * @brief Retrieve the parsed int generator. + * + * @returns A pointer to a float generator. The float generator becomes + * the responsibility of the caller. + * @throws An AttributeDefinitionException if the types are wrong. + */ + virtual IntGenerator * getIntGenerator(){ IntGenerator * val = _generator; _generator=0x0; return val; } + + protected: + /*! + * @brief The default int value. Meaningless if _required is true. + */ + int _default; + + /*! + * @brief The parsed generator. + */ + IntGenerator * _generator; + }; +} // namespace Menge +#endif // __ATTRIBUTE_H__ diff --git a/src/Menge/MengeCore/PluginEngine/AttributeSet.cpp b/src/Menge/MengeCore/PluginEngine/AttributeSet.cpp new file mode 100644 index 00000000..4bbdb8eb --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/AttributeSet.cpp @@ -0,0 +1,257 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AttributeSet.h" +#include "Attribute.h" +#include "tinyxml.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of AttributeSet + ///////////////////////////////////////////////////////////////////// + + AttributeSet::AttributeSet():_attrs() { + } + + ///////////////////////////////////////////////////////////////////// + + AttributeSet::~AttributeSet() { + for ( size_t i = 0; i < _attrs.size(); ++i ) { + delete _attrs[ i ]; + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addBoolAttribute( const std::string & name, bool required, bool defValue ) { + if ( isUniqueName( name ) ) { + Attribute * attr = new BoolAttribute( name, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add a boolean attribute with the key value: \"" << name << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addIntAttribute( const std::string & name, bool required, int defValue ) { + if ( isUniqueName( name ) ) { + Attribute * attr = new IntAttribute( name, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add an int attribute with the key value: \"" << name << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addSizeTAttribute( const std::string & name, bool required, size_t defValue ) { + if ( isUniqueName( name ) ) { + Attribute * attr = new SizeTAttribute( name, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add a size_t attribute with the key value: \"" << name << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addFloatAttribute( const std::string & name, bool required, float defValue ) { + if ( isUniqueName( name ) ) { + Attribute * attr = new FloatAttribute( name, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add a float attribute with the key value: \"" << name << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addFloatDistAttribute( const std::string & prefix, bool required, float defValue, float scale ) { + if ( isUniqueName( prefix ) ) { + Attribute * attr = new FloatDistributionAttribute( prefix, required, defValue, scale ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add a float distribution attribute with the key value: \"" << prefix << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addVec2DDistAttribute( bool required, const Vector2 & defValue, float scale ) { + // Confirm that this is the only Vec2D generator + for ( size_t i = 0; i < _attrs.size(); ++i ) { + if ( dynamic_cast< Vec2DDistributionAttribute * >( _attrs[i] ) != 0x0 ) { + std::stringstream ss; + ss << "Trying to add multiple Vector 2D distribution attributes to a factory. This is not allowed."; + throw AttributeDefinitionException( ss.str() ); + } + } + Attribute * attr = new Vec2DDistributionAttribute( required, defValue, scale ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addIntDistAttribute( const std::string & prefix, bool required, int defValue ) { + if ( isUniqueName( prefix ) ) { + Attribute * attr = new IntDistributionAttribute( prefix, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add an int distribution attribute with the key value: \"" << prefix << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::addStringAttribute( const std::string & name, bool required, const std::string & defValue ) { + if ( isUniqueName( name ) ) { + Attribute * attr = new StringAttribute( name, required, defValue ); + _attrs.push_back( attr ); + return _attrs.size() - 1; + } else { + std::stringstream ss; + ss << "Trying to add a string attribute with the key value: \"" << name << "\". Previous attribute already using that name."; + throw AttributeDefinitionException( ss.str() ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void AttributeSet::clear() { + for ( size_t i = 0; i < _attrs.size(); ++i ) { + _attrs[i]->clear(); + } + } + + ///////////////////////////////////////////////////////////////////// + + bool AttributeSet::extract( TiXmlElement * node ) { + bool valid = true; + // Don't simply die at the first attribute error. Find multiple errors + // and THEN throw an exception. + for ( size_t i = 0; i < _attrs.size(); ++i ) { + valid = valid && _attrs[i]->extract( node ); + } + return valid; + } + + ///////////////////////////////////////////////////////////////////// + + bool AttributeSet::isUniqueName( const std::string & name ) { + // This requires every name to be unique + // This includes distribution prefixes. A distribution prefix CANNOT be + // the same as another attribute name. + for ( size_t i = 0; i < _attrs.size(); ++i ) { + if ( _attrs[i]->getName() == name ) return false; + } + return true; + } + + ///////////////////////////////////////////////////////////////////// + + int AttributeSet::getInt( size_t propID ) { + return _attrs[ propID ]->getInt(); + } + + ///////////////////////////////////////////////////////////////////// + + size_t AttributeSet::getSizeT( size_t propID ) { + return _attrs[ propID ]->getSizeT(); + } + + ///////////////////////////////////////////////////////////////////// + + bool AttributeSet::getBool( size_t propID ) { + return _attrs[ propID ]->getBool(); + } + + ///////////////////////////////////////////////////////////////////// + + float AttributeSet::getFloat( size_t propID ) { + return _attrs[ propID ]->getFloat(); + } + + ///////////////////////////////////////////////////////////////////// + + std::string AttributeSet::getString( size_t propID ) { + return _attrs[ propID ]->getString(); + } + + ///////////////////////////////////////////////////////////////////// + + FloatGenerator * AttributeSet::getFloatGenerator( size_t propID ) { + return _attrs[ propID ]->getFloatGenerator(); + } + + ///////////////////////////////////////////////////////////////////// + + Vec2DGenerator * AttributeSet::getVec2DGenerator( size_t propID ) { + return _attrs[ propID ]->getVec2DGenerator(); + } + + ///////////////////////////////////////////////////////////////////// + + IntGenerator * AttributeSet::getIntGenerator( size_t propID ) { + return _attrs[ propID ]->getIntGenerator(); + } + + ///////////////////////////////////////////////////////////////////// + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/AttributeSet.h b/src/Menge/MengeCore/PluginEngine/AttributeSet.h new file mode 100644 index 00000000..e8cb4a93 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/AttributeSet.h @@ -0,0 +1,337 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AttributeSet.h + * @brief Defines the set of element attributes. + */ + +#ifndef __ATTRIBUTE_SET_H__ +#define __ATTRIBUTE_SET_H__ + +#include +#include "CoreConfig.h" +#include "Math/Vector2.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + class Attribute; + namespace Math { + class FloatGenerator; + class IntGenerator; + class Vec2DGenerator; + } + using namespace Math; + /*! + * @brief A set of attributes. + * + * This is a utility class for facilitating parsing XML specifications. + * It is used for elements who can be completely defined strictly via + * XML attributes in a single tag. It allows handling these types of + * specifications without explicitly dealing with the XML. + * + * Making use of this utility is a two-step process. + * 1 Define the expected attributes. + * 2 Use the extracted values to initialize the agent. + * + * Every element factory has a built-in attribute set (called _attrSet). + * In the factory's constructor, simply make calls into the attribute set + * providing the details of each desired attribute. The attribute set + * returns a unique identifier for each new attribute. Store these + * attributes, you will use them to extract the parsed values later. + * + * In the setFromXML function, first, call the parent class's implementation + * of the function. If there is a parsing error, an exception will be automatically + * thrown. You don't need to catch it. The framework will catch the exception and + * respond accordingly. Assuming there is no exception, simply use the + * stored identifiers to extract values from the attribute set and set it to + * the instance. + */ + class MENGE_API AttributeSet { + public: + /*! + * @brief Constructor. + */ + AttributeSet(); + + /*! + * @brief Destructor. + */ + ~AttributeSet(); + + /*! + * @brief Adds a boolean attribute to the set. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addBoolAttribute( const std::string & name, bool required, bool defValue=false ); + + /*! + * @brief Adds an integer attribute to the set. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addIntAttribute( const std::string & name, bool required, int defValue=0 ); + + /*! + * @brief Adds a size_t attribute to the set. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addSizeTAttribute( const std::string & name, bool required, size_t defValue=0 ); + + /*! + * @brief Adds a float attribute to the set. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addFloatAttribute( const std::string & name, bool required, float defValue=0 ); + + /*! + * @brief Adds a float distribution attribute to the set. + * + * @param prefix The prefix for the distribution (provide the empty string to use defaults.) + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @param scale The scale value for this distribution. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addFloatDistAttribute( const std::string & prefix, bool required, float defValue, float scale ); + + /*! + * @brief Adds a Vector2 distribution attribute to the set. + * + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @param scale The optional scale value for this distribution. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addVec2DDistAttribute( bool required, const Vector2 & defValue, float scale=1.f ); + + /*! + * @brief Adds an integer distribution attribute to the set. + * + * @param prefix The prefix for the distribution (provide the empty string to use defaults.) + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addIntDistAttribute( const std::string & prefix, bool required, int defValue=0 ); + + /*! + * @brief Adds an integer attribute to the set. + * + * @param name The attribute name. + * @param required Whether or not the attribute is required (true) + * or not (false). + * @param defValue The default value for the attribute if none is provided. + * This value will serve no purpose if required is passed true. + * @returns The unique identifier for this attribute. + * @throws An AttributeDefinitionException if the attribute name is not unique. + */ + size_t addStringAttribute( const std::string & name, bool required, const std::string & defValue="" ); + + /*! + * @brief Prepares the set to parse a new instance. + */ + void clear(); + + /*! + * @brief Parses the node for the given attributes. + * + * @param node The XML node containing the attributes. + * @returns True on sucessful extraction, false otherwise. + */ + bool extract( TiXmlElement * node ); + + /*! + * @brief Retrieve the int value from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns The int value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + int getInt( size_t propID ); + + /*! + * @brief Retrieve the size_t value from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns The size_t value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + size_t getSizeT( size_t propID ); + + /*! + * @brief Retrieve the int value from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns The boolean value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + bool getBool( size_t propID ); + + /*! + * @brief Retrieve the float value from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns The float value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + float getFloat( size_t propID ); + + /*! + * @brief Retrieve the string value from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns The int value. + * @throws An AttributeDefinitionException if the types are wrong. + */ + std::string getString( size_t propID ); + + /*! + * @brief Retrieve the float generator from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns A pointer to the float generator. The caller now is responsible + * for the memory to which this pointer refers. + * @throws An AttributeDefinitionException if the types are wrong. + */ + FloatGenerator * getFloatGenerator( size_t propID ); + + /*! + * @brief Retrieve the Vector2 generator from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns A pointer to the Vector2 generator. The caller now is responsible + * for the memory to which this pointer refers. + * @throws An AttributeDefinitionException if the types are wrong. + */ + Vec2DGenerator * getVec2DGenerator( size_t propID ); + + /*! + * @brief Retrieve the int generator from the given property ID. + * + * If the attribute associated with the given property ID is of the + * wrong type, this will throw an exception. + * + * @param propID The property ID -- this is given as the + * result of AttributeSet::addAttribute. + * @returns A pointer to the int generator. The caller now is responsible + * for the memory to which this pointer refers. + * @throws An AttributeDefinitionException if the types are wrong. + */ + IntGenerator * getIntGenerator( size_t propID ); + + protected: + /*! + * @brief reports if the new attribute name clashes with a previous attribute name. + */ + bool isUniqueName( const std::string & name ); + + /*! + * @brief The attributes in the set. + */ + std::vector< Attribute * > _attrs; + }; +} // namespace Menge +#endif // __ATTRIBUTE_SET_H__ diff --git a/src/Menge/MengeCore/PluginEngine/Element.h b/src/Menge/MengeCore/PluginEngine/Element.h new file mode 100644 index 00000000..bef23dc8 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/Element.h @@ -0,0 +1,111 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Element.h + * @brief Base class for all Menge elements. + */ + +#ifndef __ELEMENT_H__ +#define __ELEMENT_H__ + +#include "CoreConfig.h" + +namespace Menge { + + // forward declarations + namespace SceneGraph { + class GLNode; + } + + namespace BFSM { + class Task; + } + + /*! + * @brief The basic interface of extendible Menge Elements. + * + * A Menge element is a component of the Menge framework. A particular + * crowd simulator is defined by the instantiation of various types of + * elements. + */ + class MENGE_API Element { + public: + /*! + * @brief This supplants the destructor. + * + * In order to avoid potential problems in windows when + * dlls do not share the same c-runtime library, the destructor + * is held to be protected. To garbage collect a Condition, + * the destroy method should be called (which in turn, will call + * the destructor from its own memory space, averting run-time + * crashes). + * + * Once this has been called, the TransitionTarget no longer exists. + * Calling methods or accessing members will produce indetermine behavior + * (most likely errors). + */ + void destroy() { delete this; } + + /*! + * @brief Return an optional task associated with this element. + * + * An element can have an accompanying Task for performing synchronized work. + * Most element implementations will not have a task. If a task is required, + * override this function to return an appropriate instance of the required + * task. + * + * @returns A pointer to the required task. It is the responsibility + * of the caller to free the memory of the provided task by + * calling its destroy method. + */ + virtual BFSM::Task * getTask() { return 0x0; } + + /*! + * @brief Returns an optional visualization element associated with the element. + * + * This element will simply be added to the scene graph and will be destroyed by + * the scene graph. It should not be used if the visualization is context dependent. + * + * @returns A pointer to the scene graph node element. + */ + virtual SceneGraph::GLNode * getSGNode() { return 0x0; } + }; +} // namespace Menge + +#endif // __ELEMENT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/ElementDatabase.h b/src/Menge/MengeCore/PluginEngine/ElementDatabase.h new file mode 100644 index 00000000..9bd94d07 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/ElementDatabase.h @@ -0,0 +1,209 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElementDatabase.h + * @brief The base (templated) implementation of the database + * that tracks plug-in elements. + */ + +#ifndef __ELEMENT_DATABASE_H__ +#define __ELEMENT_DATABASE_H__ + +#include +#include +#include "tinyxml.h" +#include "Logger.h" + +namespace Menge { + + /*! + * @brief The base functionality of an element database. + * + * Queries for parsing element XML and instantiating the appropriate elements + * for the finite state machine pass through the appropriate element database. + * + * For plug-in-compatible elements, they should have their own database and + * factory. For simplicity, they should sub-class a specialization of this template. + */ + template < class Factory, class Element > + class ElementDB { + public: + /*! + * @brief Reports the number of registered target factories. + * + * @returns The number of registered target factories. + */ + static inline size_t count() { return _factories.size(); } + + /*! + * @brief Returns an instance of the TransitionTarget defined in the XML node. + * + * The caller is responsible for deleting the TransitionTarget instance. + * + * @param node The tinyxml node holding the TransitionTarget definition. + * @param behaveFldr The path to the behavior file. If the transition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A pointer to a TransitionTarget instance for the given Condtion XML data. + * If no valid TargetFactory matches the data, NULL is returned. + */ + static Element * getInstance( TiXmlElement * node, const std::string & behaveFldr ) { + // extract type name + const char * typeCStr = node->Attribute( "type" ); + if ( ! typeCStr ) { + logger << Logger::ERR_MSG << "A " << getElementName() << " tag has been provided with no \"type\" attribute on line " << node->Row() << "\n"; + return 0x0; + } + std::string typeName( typeCStr ); + typename std::list< Factory * >::iterator itr = _factories.begin(); + for ( ; itr != _factories.end(); ++itr ) { + const Factory * factory = *itr; + if ( factory->thisFactory( typeName ) ) { + // try to parse it + Element * element = factory->createInstance( node, behaveFldr ); + if ( ! element ) { + logger << Logger::ERR_MSG << "The " << getElementName() << " of type \"" << typeName << "\" defined on line " << node->Row() << " could not be instantiated.\n"; + return 0x0; + } + return element; + } + } + + logger << Logger::ERR_MSG << "Found an undefined " << getElementName() << " type (" << typeName << ") on line " << node->Row() << "\n"; + return 0x0; + } + + /*! + * @brief Initializes the database. + */ + static void initialize() { + if ( ! _initialized ) { + _initialized = true; + addBuiltins(); + } + } + + /*! + * @brief Adds the built-in factories to the database. + * + * Sub-classes will specialize this function to add the built-in factory + * types. + */ + static void addBuiltins(); + + /*! + * @brief Adds a new Target factory to the database. + * + * The database takes ownership of the data pointed to. + * To be added, the new factory must have a unique name to all + * previous actions. If the factory *cannot* be added, it will + * be deleted. + * + * @param factory A pointer to the factory to add. + * @returns True if the factory is successfully added, false othrewise. + */ + static bool addFactory( Factory * factory ) { + std::string testName( factory->name() ); + typename std::list< Factory * >::iterator itr = _factories.begin(); + for (; itr != _factories.end(); ++itr ) { + std::string prevName( (*itr)->name() ); + if ( testName == prevName ) { + logger << Logger::ERR_MSG << "Trying to add a " << getElementName() << " factory which conflicts with a previous condition factories.\n"; + logger << "\tBoth " << getElementName() << "s use the name: " << testName << ".\n"; + logger << "\tDescription of the first " << getElementName() << " type: " << (*itr)->description() << ".\n"; + logger << "\tDescription of the new " << getElementName() << " type: " << factory->description() << "."; + factory->destroy(); + return false; + } + } + _factories.push_back( factory ); + return true; + } + + /*! + * @brief Returns the name of the element managed by this database. + * + * @returns the name of the element managed by this database + */ + static std::string getElementName(); + + /*! + * @brief Removes all registered factories from the database. + */ + static void clear() { + typename std::list< Factory * >::iterator itr = _factories.begin(); + for ( ; itr != _factories.end(); ++itr ) { + (*itr)->destroy(); + } + _factories.clear(); + } + protected: + /*! + * @brief Tracks whether the database has been initialized, so that + * multiple calls to initialize will not cause problems. + */ + static bool _initialized; + + /*! + * @brief The registered factories. + */ + static std::list< Factory * > _factories; + + }; + + // The two functions, addBuiltins and getElementName are *not* defined in-line + // because of a quirk of visual studio's template system. By defining the + // default functionality for the template OUTSIDE the class definition, + // these can be properly, explicitly specialized in separate C++ files. + + template < class Factory, class Element > + void ElementDB< Factory, Element >::addBuiltins() {} + + template < class Factory, class Element > + std::string ElementDB< Factory, Element >::getElementName(){ return "unnamed"; } + + template < class Factory, class Element > + bool ElementDB< Factory, Element >::_initialized = false; + + template < class Factory, class Element > + std::list< Factory * > ElementDB< Factory, Element >::_factories; +} // namespace Menge + +#endif // __ELEMENT_DATABASE_H__ diff --git a/src/Menge/MengeCore/PluginEngine/ElementFactory.h b/src/Menge/MengeCore/PluginEngine/ElementFactory.h new file mode 100644 index 00000000..6d7a7e25 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/ElementFactory.h @@ -0,0 +1,188 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElementFactory.h + * @brief The base (templated) implementation of a factory for + * a plug-in element. + */ + +#ifndef __ELEMENT_FACTORY_H__ +#define __ELEMENT_FACTORY_H__ + +#include "AttributeSet.h" + +// forward declaration +class TiXmlElement; + +namespace Menge { + + /*! + * @brief The templated base class for a plugin element + */ + template < class Element > + class ElementFactory { + public: + /*! + * @brief Default constructor. + */ + ElementFactory() {} + + /*! + * @brief This supplants the destructor. + * + * In order to preserve potential problems in windows when + * dlls do not share the same c-runtime library, the destructor + * is held to be private. To garbage collect and ConditionFactory, + * the destory method should be called (which in turn, will call + * the destructor from its own memory space, averting run-time + * crashes. + */ + void destroy() { + delete this; + } + + protected: + /*! + * @brief Destructor. + */ + virtual ~ElementFactory(){} + + public: + + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const = 0; + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const = 0; + + /*! + * @brief Reports if the xml node defines an element for this factory. + * + * This works by comparing the name attribute (if it exists) of the xml + * node with this element factory's name. + * + * @param typeName the name of the xml node in question + * @returns Returns true if the xml (appears) to specify this factory's + * element. + */ + bool thisFactory( const std::string & typeName ) const { return typeName == name(); } + + /*! + * @brief Parses the xml data. + * + * This should be overridden by sub-classes. + * + * @param node The xml node containing the data for the condition. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. It can be ignored if no file system resources are used. + * @returns A pointer to a new condition instance for this data. + * If there is an error in the xml, NULL is returned. + */ + Element * createInstance( TiXmlElement * node, const std::string & behaveFldr ) const { + Element * element = instance(); + if ( ! setFromXML( element, node, behaveFldr ) ) { + element->destroy(); + element = 0x0; + } + return element; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + virtual Element * instance() const = 0; + + /*! + * @brief Given a pointer to an element instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute will be the element's type. + * (i.e. ElementFactory::thisFactory has already been called and returned true.) + * If sub-classes of ElementFactory introduce *new* parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param element A pointer to the element whose attributes are to be set. + * @param node The XML node containing the element attributes. + * @param specFldr The path to the defining file. If the element references + * resources in the file system, it should be defined relative + * to this file location. This is the folder containing + * that path. For elements defined in behavior files, this will + * be the path to that file; the same is true for those defined in + * scene files + * @returns A boolean reporting success (true) or failure (false). + * @throws An AttributeException if there is a problem in extracting values from the + * attribute set. + */ + virtual bool setFromXML( Element * element, TiXmlElement * node, const std::string & specFldr ) const { + _attrSet.clear(); + return _attrSet.extract( node ); + } + + /*! + * @brief The attribute set for this factory. + */ + mutable AttributeSet _attrSet; + }; +} // namespace Menge + +#endif // __ELEMENT_FACTORY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/Plugin.cpp b/src/Menge/MengeCore/PluginEngine/Plugin.cpp new file mode 100644 index 00000000..eb7f8c0f --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/Plugin.cpp @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Plugin.h" +#include +#include "Logger.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Plugin + ///////////////////////////////////////////////////////////////////// + + Plugin::Plugin( const std::string & filename ):_handle(0), _registerFcnAddr(0x0), _getNameFcnAddr(0x0), _getDescFcnAddr(0x0) { + // This might throw a std::runtime_error which will immediately propagate upwards + try { + _handle = SharedLibrary::Load( filename ); + } catch ( std::exception & e ) { + logger << Logger::ERR_MSG << e.what(); + throw; + } + + try { + _registerFcnAddr = SharedLibrary::GetFunctionPointer< RegisterPluginFcn >( _handle, "registerPlugin" ); + _getNameFcnAddr = SharedLibrary::GetFunctionPointer< GetCharPtrFcn >( _handle, "getName" ); + _getDescFcnAddr = SharedLibrary::GetFunctionPointer< GetCharPtrFcn >( _handle, "getDescription" ); + } catch( std::exception & e) { + logger << Logger::ERR_MSG << e.what(); + SharedLibrary::Unload( _handle ); + throw; + } + } + + ///////////////////////////////////////////////////////////////////// + + Plugin::~Plugin() { + SharedLibrary::Unload( _handle ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/Plugin.h b/src/Menge/MengeCore/PluginEngine/Plugin.h new file mode 100644 index 00000000..d2ba4c8a --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/Plugin.h @@ -0,0 +1,135 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Plugin.h + * @brief The basic specification of a plug in + */ + +#ifndef __PLUGIN_H__ +#define __PLUGIN_H__ + +#include +#include "SharedLibrary.h" + +namespace Menge { + + class PluginEngine; + + /*! + * @brief The base plug-in class + */ + class Plugin { + public: + /*! + * @brief Plugin function pointer for functions which return strings. + */ + typedef const char * GetCharPtrFcn(); + + /*! + * @brief Declaration of registration function pointer type + */ + typedef void RegisterPluginFcn( PluginEngine * ); + + /*! + * @brief Constructor. + * + * @param filename The filename of the plugin to instantiate. + * @throws std::exception if there is a problem initializing the plugin. + */ + MENGE_API Plugin( const std::string & filename ); + + /*! + * @brief Destructor. + */ + MENGE_API ~Plugin(); + + /*! + * @brief Registers the plugin to the PluginEngine + * + * @param engine The PluginEngine + */ + MENGE_API void registerPlugin( PluginEngine * engine ) { + _registerFcnAddr( engine ); + } + + /*! + * @brief Returns the name of the plugin + * + * @returns The name of the plug-in. + */ + MENGE_API const char * getName() { + return _getNameFcnAddr(); + } + + /*! + * @brief Returns the description of the plugin + * + * @returns The description of the plug-in. + */ + MENGE_API const char * getDescription() { + return _getDescFcnAddr(); + } + + private: + /*! + * @brief The shared library handle. + */ + SharedLibrary::HandleType _handle; + + /*! + * @brief A function pointer to the plugin registration function. + * + * This should get initialized in the constructor + */ + RegisterPluginFcn * _registerFcnAddr; + + /*! + * @brief A function pointer to the function which returns the plugin name + */ + GetCharPtrFcn * _getNameFcnAddr; + + /*! + * @brief A function pointer to the function which returns the plugin description + */ + GetCharPtrFcn * _getDescFcnAddr; + }; + +} // namespace Menge + +#endif // __PLUGIN_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/PluginEngine.cpp b/src/Menge/MengeCore/PluginEngine/PluginEngine.cpp new file mode 100644 index 00000000..b4d33b07 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/PluginEngine.cpp @@ -0,0 +1,252 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +//#define PLUGIN_EXPORT 1 + +#include +#include "PluginEngine.h" +#include "os.h" +#include "SimulatorDB.h" +#include "Orca/ORCADBEntry.h" +#include "PedVO/PedVODBEntry.h" +#include "Actions/ActionDatabase.h" +#include "Transitions/ConditionDatabase.h" +#include "Transitions/TargetDatabase.h" +#include "VelocityComponents/VelComponentDatabase.h" +#include "VelocityModifiers/VelModifierDatabase.h" +#include "Tasks/TaskDatabase.h" +#include "Goals/GoalDatabase.h" +#include "GoalSelectors/GoalSelectorDatabase.h" +#include "Elevations/ElevationDatabase.h" +#include "SpatialQueries/SpatialQueryDatabase.h" +#include "AgentGenerators/AgentGeneratorDatabase.h" +#include "ProfileSelectors/ProfileSelectorDatabase.h" +#include "StateSelectors/StateSelectorDatabase.h" +#include "Events/EventTriggerDB.h" +#include "Events/EventEffectDB.h" +#include "Events/EventTargetDB.h" +#include "ObstacleSets/ObstacleSetDatabase.h" +#include "Logger.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PluginEngine + ///////////////////////////////////////////////////////////////////// + + PluginEngine::PluginEngine( SimulatorDB * simDB ): _plugins(), _simDB(simDB) { + registerModelDBEntry( new ORCA::DBEntry() ); + registerModelDBEntry( new PedVO::DBEntry() ); + BFSM::ActionDB::initialize(); + BFSM::ConditionDB::initialize(); + BFSM::TargetDB::initialize(); + BFSM::VelCompDB::initialize(); + BFSM::VelModDB::initialize(); + BFSM::TaskDB::initialize(); + BFSM::GoalDB::initialize(); + BFSM::GoalSelectorDB::initialize(); + Agents::ElevationDB::initialize(); + Agents::SpatialQueryDB::initialize(); + Agents::AgentGeneratorDB::initialize(); + Agents::ObstacleSetDB::initialize(); + Agents::ProfileSelectorDB::initialize(); + Agents::StateSelectorDB::initialize(); + EventEffectDB::initialize(); + EventTriggerDB::initialize(); + EventTargetDB::initialize(); + } + + ///////////////////////////////////////////////////////////////////// + + PluginEngine::~PluginEngine() { + } + + ///////////////////////////////////////////////////////////////////// + + size_t PluginEngine::loadPlugins( const std::string & pluginFldr ) { + // 1. get all files in pluginFldr that conform to a platform-dependent + // naming convention. + // 2. For each one, try to open it and determine if it has the interface + // expected for this plugin engine + // 3. If it does, register it with the appropriate manager. + // (NOt entirely sure what this means yet...ultimately, the manager + // has to be able to provide information about the entity in the + // plug-in and provide the ability to insantiate it. "information" + // may also include the ability to parse itself from the xml. + + StringList files; + #ifdef _MSC_VER + std::string extension( "*.dll" ); + #else + std::string extension( "*.so" ); + #endif + if ( !os::listdir( pluginFldr, files, extension ) ) { + return 0; + } + + StringListCItr itr = files.begin(); + for ( ; itr != files.end(); ++itr ) { + std::string fullPath; + if ( ! os::path::absPath( os::path::join( 2, pluginFldr.c_str(), (*itr).c_str() ), fullPath ) ) { + logger << Logger::ERR_MSG << "Unable to get absolute path for " << (*itr); + continue; + } + Plugin * plugin; + try { + plugin = new Plugin( fullPath ); + } catch ( std::exception & ) { + logger << Logger::ERR_MSG << "Failed loading " << fullPath << " as a plug-in"; + continue; + } + logger << Logger::INFO_MSG << "Loaded: " << plugin->getName() << "\n";; + logger << "\t" << plugin->getDescription(); + plugin->registerPlugin( this ); + _plugins.insert( PluginMap::value_type( (*itr), plugin ) ); + } + + return files.size(); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerModelDBEntry( SimulatorDBEntry * dbEntry ) { + _simDB->registerEntry( dbEntry ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerActionFactory( BFSM::ActionFactory * factory ) { + BFSM::ActionDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerConditionFactory( BFSM::ConditionFactory * factory ) { + BFSM::ConditionDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerTargetFactory( BFSM::TargetFactory * factory ) { + BFSM::TargetDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerVelCompFactory( BFSM::VelCompFactory * factory ) { + BFSM::VelCompDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerVelModFactory( BFSM::VelModFactory * factory ) { + BFSM::VelModDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerTaskFactory( BFSM::TaskFactory * factory ) { + BFSM::TaskDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerGoalFactory( BFSM::GoalFactory * factory ) { + BFSM::GoalDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerGoalSelectorFactory( BFSM::GoalSelectorFactory * factory ) { + BFSM::GoalSelectorDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerElevationFactory( Agents::ElevationFactory * factory ) { + Agents::ElevationDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerSpatialQueryFactory( Agents::SpatialQueryFactory * factory ) { + Agents::SpatialQueryDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerAgentGeneratorFactory( Agents::AgentGeneratorFactory * factory ) { + Agents::AgentGeneratorDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerObstacleSetFactory( Agents::ObstacleSetFactory * factory ) { + Agents::ObstacleSetDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerProfileSelectorFactory( Agents::ProfileSelectorFactory * factory ) { + Agents::ProfileSelectorDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerStateSelectorFactory( Agents::StateSelectorFactory * factory ) { + Agents::StateSelectorDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerEventEffectFactory( EventEffectFactory * factory ) { + EventEffectDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerEventTriggerFactory( EventTriggerFactory * factory ) { + EventTriggerDB::addFactory( factory ); + } + + ///////////////////////////////////////////////////////////////////// + + void PluginEngine::registerEventTargetFactory( EventTargetFactory * factory ) { + EventTargetDB::addFactory( factory ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/PluginEngine.h b/src/Menge/MengeCore/PluginEngine/PluginEngine.h new file mode 100644 index 00000000..0959912c --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/PluginEngine.h @@ -0,0 +1,253 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PluginEngine.h + * @brief Definition of the plug-in architecture. + */ + +#ifndef __PLUGIN_ENGINE_H__ +#define __PLUGIN_ENGINE_H__ + +#include +#include +#include "Plugin.h" + +namespace Menge { + + // Forward declaration + class SimulatorDBEntry; + class SimulatorDB; + + namespace BFSM { + class ActionFactory; + class ConditionFactory; + class TargetFactory; + class VelCompFactory; + class VelModFactory; + class TaskFactory; + class GoalFactory; + class GoalSelectorFactory; + } + + namespace Agents { + class ElevationFactory; + class SpatialQueryFactory; + class AgentGeneratorFactory; + class ProfileSelectorFactory; + class StateSelectorFactory; + class ObstacleSetFactory; + } + + class EventTriggerFactory; + class EventEffectFactory; + class EventTargetFactory; + + /*! + * @brief Mapping from the file name of the dynamic library to a pointer to + * the loaded plugin. + */ + typedef std::map< std::string, Plugin * > PluginMap; + + /*! + * @brief The class responsible for finding, managing, and deleting + * plugins. + */ + class PluginEngine { + public: + // TODO: Make the make SimulatorDB a PedestrianDB and make it static, like + // the ActionFactory + /*! + * @brief Default constructor. + * + * @param simDB A simulator database for pedestrian model registration + */ + MENGE_API PluginEngine( SimulatorDB * simDB ); + + /*! + * @brief Destructor + */ + MENGE_API ~PluginEngine(); + + /*! + * @brief Initialize plug-ins from the given directory. + * + * @param pluginFldr The folder to search for plugins. + * @returns The number of plugins successfully loaded. + */ + MENGE_API size_t loadPlugins( const std::string & pluginFldr ); + + /*! + * @brief Register a simulator database entry. + * + * @param dbEntry An instance of a model database entry to register. + */ + MENGE_API void registerModelDBEntry( SimulatorDBEntry * dbEntry ); + + /*! + * @brief Register an ActionFactory. + * + * @param factory An instance of the ActionFactory to register + */ + MENGE_API void registerActionFactory( BFSM::ActionFactory * factory ); + + /*! + * @brief Register a ConditionFactory. + * + * @param factory An instance of the ConditionFactory to register + */ + MENGE_API void registerConditionFactory( BFSM::ConditionFactory * factory ); + + /*! + * @brief Register a TargetFactory. + * + * @param factory An instance of the TargetFactory to register + */ + MENGE_API void registerTargetFactory( BFSM::TargetFactory * factory ); + + /*! + * @brief Register a VelCompFactory. + * + * @param factory An instance of the VelCompFactory to register + */ + MENGE_API void registerVelCompFactory( BFSM::VelCompFactory * factory ); + + /*! + * @brief Register a VelModFactory. + * + * @param factory An instance of the VelModifier to register + */ + MENGE_API void registerVelModFactory( BFSM::VelModFactory * factory ); + + /*! + * @brief Register a TaskFactory. + * + * @param factory An instance of the TaskFactory to register + */ + MENGE_API void registerTaskFactory( BFSM::TaskFactory * factory ); + + /*! + * @brief Register a GoalFactory. + * + * @param factory An instance of the GoalFactory to register + */ + MENGE_API void registerGoalFactory( BFSM::GoalFactory * factory ); + + /*! + * @brief Register a GoalSelectorFactory. + * + * @param factory An instance of the GoalSelectorFactory to register + */ + MENGE_API void registerGoalSelectorFactory( BFSM::GoalSelectorFactory * factory ); + + /*! + * @brief Register an ElevationFactory. + * + * @param factory An instance of the ElevationFactory to register + */ + MENGE_API void registerElevationFactory( Agents::ElevationFactory * factory ); + + /*! + * @brief Register an SpatialQueryFactory. + * + * @param factory An instance of the SpatialQueryFactory to register + */ + MENGE_API void registerSpatialQueryFactory( Agents::SpatialQueryFactory * factory ); + + /*! + * @brief Register an AgentGeneratorFactory. + * + * @param factory An instance of the AgentGeneratorFactory to register + */ + MENGE_API void registerAgentGeneratorFactory( Agents::AgentGeneratorFactory * factory ); + + /*! + * @brief Register an ObstacleSetFactory. + * + * @param factory An instance of the ObstacleSetFactory to register + */ + MENGE_API void registerObstacleSetFactory( Agents::ObstacleSetFactory * factory ); + + /*! + * @brief Register an ProfileSelectorFactory. + * + * @param factory An instance of the ProfileSelectorFactory to register + */ + MENGE_API void registerProfileSelectorFactory( Agents::ProfileSelectorFactory * factory ); + + /*! + * @brief Register an StateSelectorFactory. + * + * @param factory An instance of the StateSelectorFactory to register + */ + MENGE_API void registerStateSelectorFactory( Agents::StateSelectorFactory * factory ); + + /*! + * @brief Register an EventEffectFactory. + * + * @param factory An instance of the EventEffectFactory to register + */ + MENGE_API void registerEventEffectFactory( EventEffectFactory * factory ); + + /*! + * @brief Register an EventTriggerFactory. + * + * @param factory An instance of the EventTriggerFactory to register + */ + MENGE_API void registerEventTriggerFactory( EventTriggerFactory * factory ); + + /*! + * @brief Register an EventTargetFactory. + * + * @param factory An instance of the EventTargetFactory to register + */ + MENGE_API void registerEventTargetFactory( EventTargetFactory * factory ); + + protected: + /*! + * @brief The loaded plugins. + */ + PluginMap _plugins; + + /*! + * @brief The simulator database for registration. + */ + SimulatorDB * _simDB; + }; +} // namespace Menge +#endif // __PLUGIN_ENGINE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/PluginEngine/SharedLibrary.h b/src/Menge/MengeCore/PluginEngine/SharedLibrary.h new file mode 100644 index 00000000..7e97be37 --- /dev/null +++ b/src/Menge/MengeCore/PluginEngine/SharedLibrary.h @@ -0,0 +1,212 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// Plugin architecture example // +// // +// This code serves as an example to the plugin architecture discussed in // +// the article and can be freely used // +/////////////////////////////////////////////////////////////////////////////// +/*! + * @file SharedLibrary.h + * @brief Functions for loading and unloading shared libraries. + */ +#ifndef __PLUGIN_SHARED_LIBRARY_H__ +#define __PLUGIN_SHARED_LIBRARY_H__ + +#include "CoreConfig.h" +#include "Logger.h" + +#include +#include +#include + +#if defined( PLUGIN_WIN32 ) + +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN +#include + +#elif defined( PLUGIN_LINUX ) + +#include + +#else + +#error Please implement the shared library functions for your system + +#endif + +namespace Menge { + + #if defined( PLUGIN_WIN32 ) + + /*! + * @brief Class with static functions for loading/unloading shared libraries + */ + class SharedLibrary { + public: + /*! + * @brief Handle by which DLLs are referenced. + */ + typedef HMODULE HandleType; + + /*! + * @brief Loads the DLL from the given path. + * + * @param Path of the dll to be loaded. + * @returns The Handle for the DLL + * @throws std::runtime_error if there is an error in loading the dll + */ + MENGE_API static HandleType Load( const std::string &path ) { + HMODULE moduleHandle = ::LoadLibraryA( path.c_str() ); + if( moduleHandle == NULL ) { + throw std::runtime_error("Could not load DLL"); + } + + return moduleHandle; + } + + /*! + * @brief Unloads the DLL for the given handle + * + * @param The Handle for the DLL + * @throws std::runtime_error if there is an error in unloading the dll + */ + MENGE_API static void Unload( HandleType sharedLibraryHandle ) { + BOOL result = ::FreeLibrary( sharedLibraryHandle ); + if ( result == FALSE ) { + throw std::runtime_error ("Could not unload DLL" ); + } + } + + /*! + * @brief Templated class for returning a pointer to a function with the + * given signature from the indicated dll. + * + * @param handle The dll's handle. + * @param funcName The name of the function + * @returns The desired function pointer. + * @throws std::runtime_error if there is an error in getting the pointer. + */ + template< typename TSignature > + static TSignature * GetFunctionPointer( HandleType handle, const std::string & funcName ) { + FARPROC functionAddress = ::GetProcAddress( handle, funcName.c_str() ); + if(functionAddress == NULL) { + throw std::runtime_error("Could not find exported function"); + } + + return reinterpret_cast(functionAddress); + } + + }; + + #endif + + // ----------------------------------------------------------------------- // + + #if defined( PLUGIN_LINUX ) + + /*! + * @brief Class with static functions for loading/unloading shared libraries + */ + class SharedLibrary { + public: + /*! + * @brief Handle by which shared libraries are referenced. + */ + typedef void * HandleType; + + /*! + * @brief Loads the shared library from the given path. + * + * @param path Path of the shared library to be loaded. + * @returns The Handle for the shared library + * @throws std::runtime_error if there is an error in loading the shared library + */ + MENGE_API static HandleType Load( const std::string &path ) { + void * sharedObject = ::dlopen(path.c_str(), RTLD_NOW); + if( sharedObject == NULL) { + logger << Logger::ERR_MSG << dlerror() << "\n"; + throw std::runtime_error( std::string("Could not load '") + path + "'" ); + } + + return sharedObject; + } + + /*! + * @brief Unloads the shared library for the given handle + * + * @param sharedLibraryHandle The Handle for the shared library + * @throws std::runtime_error if there is an error in unloading the shared library + */ + MENGE_API static void Unload(HandleType sharedLibraryHandle) { + int result = ::dlclose( sharedLibraryHandle ); + if(result != 0) { + throw std::runtime_error( "Could not unload shared object" ); + } + } + + /*! + * @brief Templated class for returning a pointer to a function with the + * given signature from the indicated dll. + * + * @param handle The dll's handle. + * @param funcName The name of the function + * @returns The desired function pointer. + * @throws std::runtime_error if there is an error in getting the pointer. + */ + template< typename TSignature > + static TSignature *GetFunctionPointer( HandleType handle, const std::string &funcName ) { + ::dlerror(); // clear error value + + void *functionAddress = ::dlsym( handle, funcName.c_str() ); + + const char *error = ::dlerror(); // check for error + if ( error != NULL ) { + throw std::runtime_error( "Could not find exported function" ); + } + + return reinterpret_cast(functionAddress); + } + }; + + #endif +} // namespace Menge + +#endif // __PLUGIN_SHARED_LIBRARY_H__ diff --git a/src/Menge/MengeCore/Runtime/BaseAgentContext.cpp b/src/Menge/MengeCore/Runtime/BaseAgentContext.cpp new file mode 100644 index 00000000..a6afbc6e --- /dev/null +++ b/src/Menge/MengeCore/Runtime/BaseAgentContext.cpp @@ -0,0 +1,418 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "BaseAgentContext.h" + +// MengeSim +#include "BaseAgent.h" +#include "Obstacle.h" +// MengeRuntime +#include "VisAgent.h" +// Math +#include "Math/Vector2.h" +// SceneGraph +#include "Select.h" +#include "graphCommon.h" +#include "shapes.h" +// BFSM +#include "FsmContext.h" +// STL +#include +#include + +namespace Menge { + + using namespace Math; + + //////////////////////////////////////////////////////////////////////////// + // Implementation of BaseAgentContext + //////////////////////////////////////////////////////////////////////////// + + const float BaseAgentContext::Y = 0.01f; + + //////////////////////////////////////////////////////////////////////////// + + BaseAgentContext::BaseAgentContext( VisAgent ** agents, size_t agtCount, BFSM::FsmContext * fsmCtx ): SceneGraph::SelectContext(), _selected(0x0), _state(DEFAULT_ST), + _showNbrRadius(false), _showNbr(false), _showMaxSpd(false), _showVel(false), + _showPrefVel(false), _showOrient(false), _visAgents(agents), _agtCount(agtCount), _digitCount(0), _fsmCtx(fsmCtx) + { + _digits[ MAX_TYPE_DIGITS ] = '\0'; + } + + //////////////////////////////////////////////////////////////////////////// + + BaseAgentContext::~BaseAgentContext() { + if ( _fsmCtx ) delete _fsmCtx; + } + + //////////////////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult BaseAgentContext::handleKeyboard( SDL_Event & e ) { + // TODO: Let the fsm context have a chance at this + SceneGraph::ContextResult result( false, false ); + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + if ( _fsmCtx ) { + result = _fsmCtx->handleKeyboard( e ); + } + if ( ! result.isHandled() ) { + if ( e.type == SDL_KEYDOWN ) { + if ( noMods ) { + if ( _state == DEFAULT_ST ) { + if ( e.key.keysym.sym == SDLK_r ) { + _showNbrRadius = !_showNbrRadius; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_n ) { + _showNbr = ! _showNbr; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_m ) { + _showMaxSpd = ! _showMaxSpd; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_v ) { + _showVel = ! _showVel; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_p ) { + _showPrefVel = ! _showPrefVel; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_RETURN ) { + beginIDTyping(); + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_o ) { + _showOrient = ! _showOrient; + result.set( true, true ); + } + } else if ( _state == TYPE_AGENT_ID_ST ) { + result.set( true, false ); + if ( ( e.key.keysym.sym >= SDLK_0 && e.key.keysym.sym <= SDLK_9 ) || + ( e.key.keysym.sym >= SDLK_KP0 && e.key.keysym.sym <= SDLK_KP9 ) ) { + int offset; + if ( e.key.keysym.sym <= SDLK_9 ) offset = e.key.keysym.sym - SDLK_0; + else offset = e.key.keysym.sym - SDLK_KP0; + char digit = '0' + offset; + addIDDigit( digit ); + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_RETURN ) { + finishIDTyping(); + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_SPACE ) { + cancelIDTyping(); + result.set( true, true ); + } + } + } + } + } + return result; + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawGL( int vWidth, int vHeight ) { + getOpenGLView(); + glPushAttrib( GL_ENABLE_BIT ); + glDisable( GL_LIGHTING ); + draw3DGL(); + const Agents::BaseAgent * agt = 0x0; + if ( _fsmCtx ) { + agt = ( _selected ) ? _selected->getAgent() : 0x0; + _fsmCtx->draw3DGL( agt ); + } + drawUIGL( vWidth, vHeight ); + if ( _fsmCtx ) { + _fsmCtx->drawUIGL( agt, vWidth, vHeight ); + } + glPopAttrib(); + } + + //////////////////////////////////////////////////////////////////////////// + + bool BaseAgentContext::selectGL( const SceneGraph::GLScene * scene, const SceneGraph::GLCamera & camera, int vWidth, int vHeight, int * selectPoint ) { + bool val = SceneGraph::SelectContext::selectGL( scene, camera, vWidth, vHeight, selectPoint ); + if ( val ) { + VisAgent * s = dynamic_cast< VisAgent * >( SceneGraph::Selectable::getSelectedObject() ); + val = s != _selected; + _selected = s; + } else if ( _selected ) { + _selected = 0x0; + val = true; + } + return val; + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawUIGL( int vWidth, int vHeight, bool select ) { + if (!select) { + std::stringstream ss; + ss << contextName(); + if ( _visAgents != 0x0 ) { + // Only print the help if the support is possible + ss << "\n to select by id"; + } + + if ( _selected ) { + ss << agentText( _selected->getAgent() ); + } + writeToScreen( ss.str(), SceneGraph::TextWriter::LEFT_TOP, 15, 10.f, 10.f ); + + drawIDTyping(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::draw3DGL( bool select ) { + if ( !select && _selected ) { + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + glLineWidth( 2.f ); + glDepthMask( GL_FALSE ); + glDisable( GL_DEPTH_TEST ); + const Agents::BaseAgent * agt = _selected->getAgent(); + drawNeighbors( agt ); + drawNbrRadius( agt ); + drawMaxSpeed( agt ); + drawVelocity( agt ); + drawPrefVelocity( agt ); + drawOrientation( agt ); + glPopAttrib(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawNbrRadius( const Agents::BaseAgent * agt ) { + if ( _showNbrRadius ) { + glPushAttrib( GL_POLYGON_BIT ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushMatrix(); + glTranslatef( agt->_pos.x(), Y, agt->_pos.y() ); + float r = agt->_neighborDist; + SceneGraph::Circle::drawCircle( r, 1.f, 0.75f, 0.85f, 0.05f ); + SceneGraph::Circle::drawCircle( r, 1.f, 0.75f, 0.85f, 1.f, GL_LINE ); + + glPopMatrix(); + glPopAttrib(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawNeighbors( const Agents::BaseAgent * agt ) { + if ( _showNbr ) { + glColor4f( 1.f, 1.f, 1.f, 1.f ); + + const size_t NBR_COUNT = agt->_nearAgents.size(); + for ( size_t i = 0; i < NBR_COUNT; ++i ) { + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + ss << sqrtf( agt->_nearAgents[i].distanceSquared ); + const Agents::BaseAgent * nbr = agt->_nearAgents[i].agent; + const Vector2 & p = nbr->_pos; + writeAlignedText( ss.str(), p, SceneGraph::TextWriter::CENTERED, true ); + } + // Label the nearby obstacles + glColor4f( 0.5f, 1.f, 0.5f, 1.f ); + const size_t OBST_COUNT = agt->_nearObstacles.size(); + for ( size_t i = 0; i < OBST_COUNT; ++i ) { + std::stringstream ss; + const Agents::Obstacle * obst = agt->_nearObstacles[ i ].obstacle; + ss << i; + writeAlignedText( ss.str(), obst->midPt(), SceneGraph::TextWriter::CENTERED, true ); + } + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawMaxSpeed( const Agents::BaseAgent * agt ) { + if ( _showMaxSpd ) { + glPushAttrib( GL_POLYGON_BIT ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushMatrix(); + glTranslatef( agt->_pos.x(), Y, agt->_pos.y() ); + float r = agt->_maxSpeed; + SceneGraph::Circle::drawCircle( r, 0.75f, 1.f, 0.85f, 0.05f ); + SceneGraph::Circle::drawCircle( r, 0.75f, 1.f, 0.85f, 1.f, GL_LINE ); + + glPopMatrix(); + glPopAttrib(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawVelocity( const Agents::BaseAgent * agt ) { + if ( _showVel ) { + Vector2 vel = agt->_pos + agt->_vel; + glDisable( GL_BLEND ); + glColor3f( 0.9f, 0.45f, 0.1f ); + glBegin( GL_LINES ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glVertex3f( vel.x(), Y, vel.y() ); + glEnd(); + + writeTextRadially( "v", vel, agt->_vel, true ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawPrefVelocity( const Agents::BaseAgent * agt ) { + if ( _showPrefVel ) { + Vector2 vel = agt->_pos + agt->_velPref.getPreferredVel(); + glDisable( GL_BLEND ); + glColor3f( 0.75f, 0.f, 1.f ); + glBegin( GL_LINES ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glVertex3f( vel.x(), Y, vel.y() ); + glEnd(); + + writeTextRadially( "v_p", vel, agt->_velPref.getPreferredVel(), true ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawOrientation( const Agents::BaseAgent * agt ) { + if ( _showOrient ) { + Vector2 orient = agt->_pos + agt->_orient; + glDisable( GL_BLEND ); + glColor3f( 0.75f, 0.75f, 0.75f ); + glBegin( GL_LINES ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glVertex3f( orient.x(), Y, orient.y() ); + glEnd(); + + writeTextRadially( "orient", orient, agt->_orient, true ); + } + } + //////////////////////////////////////////////////////////////////////////// + + std::string BaseAgentContext::agentText( const Agents::BaseAgent * agt ) const { + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 3 ); + + ss << "\nSelected: " << agt->_id; + ss << "\nPosition: " << agt->_pos; + ss << "\nNeighbo(r) radius: " << agt->_neighborDist; + ss << "\n(N)eighbors: " << agt->_nearAgents.size(); + ss << "\n(M)ax Speed: " << agt->_maxSpeed; + ss << "\n(O)rientation: " << agt->_orient; + ss << "\n(V)elocity: " << agt->_vel << "(" << abs( agt->_vel ) << ")"; + ss << "\n(P)ref. Velocity: " << agt->_velPref.getPreferredVel() << "(" << agt->_velPref.getSpeed() << ")"; + ss << "\nPriority: " << agt->_priority; + ss << "\nClass: " << agt->_class; + /* + // Unused properties of a BaseAgent + _radius + _maxAccel + _prefSpeed + _maxNeighbors + _maxAngVel + */ + return ss.str(); + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::beginIDTyping() { + if ( _visAgents != 0x0 ) { + _state = TYPE_AGENT_ID_ST; + _digitCount = 0; + _digits[0] = '\0'; + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::finishIDTyping() { + _state = DEFAULT_ST; + size_t id = (size_t)atoi( &_digits[0] ); // I know it must be non-negative + if ( id < _agtCount ) { + VisAgent * s = _visAgents[ id ]; + if ( s != _selected ) { + SceneGraph::Selectable::setSelectedObject( s ); + _selected = s; + } + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::cancelIDTyping() { + _state = DEFAULT_ST; + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::drawIDTyping() { + if ( _state == TYPE_AGENT_ID_ST ) { + std::stringstream ss; + ss << "Type an id to select: " << (&_digits[0] ); + ss << "\n (Enter to finish, Space to cancel)"; + writeToScreen( ss.str(), SceneGraph::TextWriter::CENTERED, 15 ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::addIDDigit( const char digit ) { + if ( _digitCount < MAX_TYPE_DIGITS ) { + // Room to add another digit. + _digits[ _digitCount ] = digit; + _digits[ _digitCount + 1 ] = '\0'; + ++_digitCount; + } + } + + //////////////////////////////////////////////////////////////////////////// + + void BaseAgentContext::activate() { + VisAgent * s = dynamic_cast< VisAgent * >( SceneGraph::Selectable::getSelectedObject() ); + if ( s != _selected ) { + _selected = s; + } + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/BaseAgentContext.h b/src/Menge/MengeCore/Runtime/BaseAgentContext.h new file mode 100644 index 00000000..edadcbfa --- /dev/null +++ b/src/Menge/MengeCore/Runtime/BaseAgentContext.h @@ -0,0 +1,310 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file BaseAgentContext.h + * @brief A basic context for interacting with and displaying + * basic agent parameters + */ + +#ifndef __BASE_AGENT_CONTEXT_H__ +#define __BASE_AGENT_CONTEXT_H__ + +#include "CoreConfig.h" +#include "Context.h" +#include + +namespace Menge { + + namespace SceneGraph { + class GLScene; + class GLCamera; + } + + namespace BFSM { + class FsmContext; + }; + + namespace Agents { + class BaseAgent; + } + + class VisAgent; + + /*! + * @brief Context class for displaying various characteristics + * of the Agents::BaseAgent class. + */ + class MENGE_API BaseAgentContext : public SceneGraph::SelectContext { + public: + /*! + * @brief Definition of the state of the context. + */ + enum BACState { + DEFAULT_ST, ///< The default operating state + TYPE_AGENT_ID_ST ///< Typing in an agent selection + }; + + /*! + * @brief Construtor + * + * @param agents An array of pointers to VisAgent instances. + * @param agtCount The number of agents contained in the array. + * @param fsmCtx A context to visualize an agent's BFSM state. + */ + BaseAgentContext( VisAgent ** agents, size_t agtCount, BFSM::FsmContext * fsmCtx=0x0 ); + + /*! + * @brief Virtual destructor. + */ + virtual ~BaseAgentContext(); + + /*! + * @brief Sets the fsm context + * + * @param ctx The context for the finite state machine. + */ + void setFSMContext( BFSM::FsmContext * ctx ) { _fsmCtx = ctx; } + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief The draw function for the context. + * + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + */ + virtual void drawGL( int vWidth, int vHeight ); + + /*! + * @brief Performs selection based on a click on screen space. + * Uses the OpenGL selection mechanism. + * + * @param scene The scene to select in. + * @param camera The camera. + * @param vWidth The width of the viewport. + * @param vHeight The height of the viewport. + * @param selectPoint The point (in screen space) at which object selection + * should take place. + * @returns A boolean indicating whether a redraw needs to take place. + */ + virtual bool selectGL( const SceneGraph::GLScene * scene, const SceneGraph::GLCamera & camera, int vWidth, int vHeight, int * selectPoint ); + + /*! + * @brief Called when the context is activated. + */ + virtual void activate(); + + protected: + /*! + * @brief Draw UI elements into the context. + * + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void drawUIGL( int vWidth, int vHeight, bool select=false ); + + /*! + * @brief Draw context elements into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( bool select=false ); + + /*! + * @brief Returns the name of the context for display. + * + * @returns The name of this context. + */ + virtual std::string contextName() const { return "BaseAgent"; } + + /*! + * @brief Creates a formatted string to be printed in the context + * for a particular agent + * + * @param agent The agent whose data is to be displayed. + * @returns A formatted string for display in the context's 2D gui. + */ + virtual std::string agentText( const Agents::BaseAgent * agent ) const; + + /*! + * @brief The drawing depth for the 3D elements + */ + static const float Y; + + /*! + * @brief The currently selected visualization agent. + */ + VisAgent * _selected; + + /*! + * @brief The state of the context. + */ + BACState _state; + + /*! + * @brief Determines if the neighbor distance is rendered + */ + bool _showNbrRadius; + + /*! + * @brief Function for drawing neighbor radius + */ + void drawNbrRadius( const Agents::BaseAgent * agt ); + + /*! + * @brief Determines if the neighbors are indicated in the view + */ + bool _showNbr; + + /*! + * @brief Function for drawing neighbor distances + */ + void drawNeighbors( const Agents::BaseAgent * agt ); + + /*! + * @brief Determines if the circle of maximum speed is displayed + */ + bool _showMaxSpd; + + /*! + * @brief Function for drawing neighbor distances + */ + void drawMaxSpeed( const Agents::BaseAgent * agt ); + + /*! + * @brief Determines if the current velocity is displayed + */ + bool _showVel; + + /*! + * @brief Function for drawing current velocity + */ + void drawVelocity( const Agents::BaseAgent * agt ); + + /*! + * @brief Determines if the preferred velocity is displayed + */ + bool _showPrefVel; + + /*! + * @brief Function for drawing the preferred velocity + */ + void drawPrefVelocity( const Agents::BaseAgent * agt ); + + /*! + * @brief Determines if the orientation of the agent is displayed. + */ + bool _showOrient; + + /*! + * @brief Function for drawing current orientation + */ + void drawOrientation( const Agents::BaseAgent * agt ); + + /*! + * @brief A pointer to the agents in the scene + */ + VisAgent ** _visAgents; + + /*! + * @brief The number of agents in the scene + */ + size_t _agtCount; + + /*! + * @brief The maximum number of digits for typing. + */ + static const unsigned int MAX_TYPE_DIGITS = 10; + + /*! + * @brief The character array for typing numbers into. + */ + char _digits[ MAX_TYPE_DIGITS + 1 ]; + + /*! + * @brief Number of typed digits. + */ + unsigned int _digitCount; + + /*! + * @brief Begins the agent typing state. + */ + void beginIDTyping(); + + /*! + * @brief Finish agent typing state. + */ + void finishIDTyping(); + + /*! + * @brief Cancels the agent typing state. + */ + void cancelIDTyping(); + + /*! + * @brief Draws the id typing state + */ + void drawIDTyping(); + + /*! + * @brief Adds a digit to the typed value + */ + void addIDDigit( const char digit ); + + /*! + * @brief An optional finite state machine context to visualize + * the computation of agent behavior. + */ + BFSM::FsmContext * _fsmCtx; + }; + +} // namespace Menge + +#endif // __BASE_AGENT_CONTEXT_H__ diff --git a/src/Menge/MengeCore/Runtime/Logger.cpp b/src/Menge/MengeCore/Runtime/Logger.cpp new file mode 100644 index 00000000..ee6a7782 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/Logger.cpp @@ -0,0 +1,376 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Logger.h" +#include +#include "os.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Logger + ///////////////////////////////////////////////////////////////////// + + Logger logger; + + ///////////////////////////////////////////////////////////////////// + + Logger::Logger():_validFile(false), _file(), _streamType(UNDEF_LOG) { + // test for the existence of the style sheet + if ( ! os::path::exists( "log.css" ) ) { + std::ofstream cssFile; + cssFile.open( "log.css", std::ios::out ); + if ( cssFile.is_open() ) { + cssFile << "table, th, td {\n"; + cssFile << "\tborder-collapse:collapse;\n"; + cssFile << "\tborder: 1px solid grey;\n"; + cssFile << "}\n"; + cssFile << "table {\n"; + cssFile << "\ttable-layout : fixed;\n"; + cssFile << "\twidth: 950 px;\n"; + cssFile << "\tmax-width: 900 px;\n"; + cssFile << "\tbackground-color : #292929;\n"; + cssFile << "}\n"; + cssFile << "td {\n"; + cssFile << "\tmin-width: 200px;\n"; + cssFile << "}\n"; + cssFile << "#content {\n"; + cssFile << "\tposition : relative;\n"; + cssFile << "}\n"; + cssFile << "body, html {\n"; + cssFile << "\tbackground: #000000;\n"; + cssFile << "\twidth: 1000px;\n"; + cssFile << "\tfont-family: Arial;\n"; + cssFile << "\tfont-size: 16px;\n"; + cssFile << "\tcolor: #C0C0C0;\n"; + cssFile << "}\n"; + cssFile << "h1 {\n"; + cssFile << "\tfont-size : 50px;\n"; + cssFile << "\tline-height : 100px;\n"; + cssFile << "\tcolor : #FFFFFF;\n"; + cssFile << "\tborder-bottom : 1px dotted #888888;\n"; + cssFile << "}\n"; + cssFile << "#logo {\n"; + cssFile << "\tposition: absolute;\n"; + cssFile << "\ttop: 0px;\n"; + cssFile << "\tright: 0px;\n"; + cssFile << "}\n"; + cssFile << ".divider {\n"; + cssFile << "\tbackground : #DDD;\n"; + cssFile << "}\n"; + cssFile << ".box {\n"; + cssFile << "\tpadding : 0px;\n"; + cssFile << "}\n"; + cssFile << ".inf {\n"; + cssFile << "\tcolor: #C0C0C0;\n"; + cssFile << "\tmin-width : 1000px;\n"; + cssFile << "\tmax-width : 1000px;\n"; + cssFile << "}\n"; + cssFile << ".err {\n"; + cssFile << "\tcolor: #EE1100;\n"; + cssFile << "\tfont-weight: bold\n"; + cssFile << "}\n"; + cssFile << ".war {\n"; + cssFile << "\tcolor: #FFCC00;\n"; + cssFile << "\tfont-weight: bold\n"; + cssFile << "}"; + + cssFile.close(); + } else { + std::cout << "Unable to create style sheet for logger\n"; + } + } + } + + ///////////////////////////////////////////////////////////////////// + + Logger::~Logger() { + close(); + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::close() { + if ( _validFile ) { + writeTail(); + _file.close(); + _validFile = false; + } + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::line() { + if ( _validFile ) { + if ( _streamType != UNDEF_LOG ) { + _file << "\n\t\n"; + } + _file << "\t\n\t\t\n\t\n"; + } else { + if ( _streamType != Logger::UNDEF_LOG ) { + std::cout << "\n"; + } + std::cout << "============================\n"; + } + _streamType = UNDEF_LOG; + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::setFile( const std::string & fileName ) { + _file.open( fileName.c_str(), std::ios::out ); + _validFile = _file.is_open(); + if ( _validFile ) { + writeHeader(); + } else { + std::cout << "Error opening file for writing a log\n"; + std::cout << "\tAll output will be written to the console\n"; + } + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::writeHeader() { + _file << "\n"; + _file << "\n"; + _file << "\n"; + _file << "Menge Log\n"; + _file << "\n"; + _file << "\n\n"; + + _file << "\n"; + _file << "
\n"; + _file << "

Menge Log

\n"; + _file << "\n"; + _file << "
\n"; + _file << "\n"; + + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::writeTail() { + if ( _streamType != UNDEF_LOG ) { + _file << "\n\t\n"; + } + _file << "
\n"; + _file << "
\n"; + _file << "
\n"; + _file << "\n"; + _file << "\n"; + } + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Simple helper function for doing text search and replace + * + * @param source The string to change. + * @param find The sub-strings to find and replace in the main string. + * @param replace The sub-string to input into the main string. + */ + inline void findAndReplace( std::string & source, const std::string & find, const std::string & replace) + { + size_t fLen = find.size(); + size_t rLen = replace.size(); + for ( size_t pos = 0; ( pos = source.find( find, pos ) ) != std::string::npos; pos += rLen ) { + source.replace(pos, fLen, replace); + } + } + + ///////////////////////////////////////////////////////////////////// + + void Logger::processText( std::string & input ) { + if ( _validFile ) { + // tags + findAndReplace( input, std::string( "<" ), std::string( "<" ) ); + findAndReplace( input, std::string( ">" ), std::string( ">" ) ); + // carriage returns + findAndReplace( input, std::string( "\n" ), std::string( "
" ) ); + // tabs + findAndReplace( input, std::string( "\t" ), std::string( "    " ) ); + } + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, const std::string & msg ) { + std::string msgStr( msg ); + logger.processText( msgStr ); + if ( logger._validFile ) { + logger._file << msgStr; + } else { + std::cout << msgStr; + } + return logger; + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, const char * msg ) { + std::string msgStr( msg ); + logger.processText( msgStr ); + if ( logger._validFile ) { + logger._file << msgStr; + } else { + std::cout << msgStr; + } + return logger; + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, long unsigned int value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + #if defined(_MSC_VER) + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, size_t value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + #else + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, unsigned int value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + #endif + ///////////////////////////////////////////////////////////////////// + + + Logger & operator<<( Logger & logger, int value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, float value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, double value ) { + if ( logger._validFile ) { + logger._file << value; + } else { + std::cout << value; + } + return logger; + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<<( Logger & logger, Logger::LogType type ) { + if ( logger._validFile ) { + if ( logger._streamType != Logger::UNDEF_LOG ) { + logger._file << "\n\t\n"; + } else { + type = Logger::INFO_MSG; + } + logger._file << "\t\n\t\t"; + + } else { + if ( logger._streamType != Logger::UNDEF_LOG ) { + std::cout << "\n"; + } else { + type = Logger::INFO_MSG; + } + switch( type ) { + case Logger::UNDEF_LOG: + std::cout << "? "; + break; + case Logger::INFO_MSG: + std::cout << "- "; + break; + case Logger::WARN_MSG: + std::cout << "! "; + break; + case Logger::ERR_MSG: + std::cout << "X "; + break; + } + } + logger._streamType = type; + return logger; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/Logger.h b/src/Menge/MengeCore/Runtime/Logger.h new file mode 100644 index 00000000..c23941d1 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/Logger.h @@ -0,0 +1,234 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Logger.h + * @brief The specificaiton of a message logger for menge, such that + * all messages to the system get properly recorded. + */ + +#ifndef __LOGGER_H__ +#define __LOGGER_H__ + +#include +#include "CoreConfig.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief An html logger - writes messages to a formatted html file. + */ + class Logger { + public: + /*! + * @brief Classfies interpretation of the subsequent + * streaming elements. + */ + enum LogType { + UNDEF_LOG, ///< No interpretation provided. + INFO_MSG, ///< Benign information - reports status. + WARN_MSG, ///< Error encountered and handled. + ERR_MSG ///< Error encountered but *not* handled. + }; + + /*! + * @brief Default constructor. + */ + MENGE_API Logger(); + + /*! + * @brief Destructor + */ + MENGE_API ~Logger(); + + /*! + * @brief Closes the logger down. + */ + MENGE_API void close(); + + /*! + * @brief Writes a solid line to the logger. + */ + MENGE_API void line(); + + /*! + * @brief Sets the logger's output file + * + * If there is an error in opening the file, the logger will default to + * writing to the console. + * + * @param fileName The file name to write the html to. + */ + MENGE_API void setFile( const std::string & fileName ); + + /*! + * @brief Writes strings to the logger based on current status. + * + * @param logger A reference to a logger. + * @param msg The string to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, const std::string & msg ); + + /*! + * @brief Writes strings to the logger based on current status. + * + * @param logger A reference to a logger. + * @param msg The string to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, const char * msg ); + + + /*! + * @brief Writes long unsigned int to the logger based on current status. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, long unsigned int value ); + + #if defined(_MSC_VER) + /*! + * @brief Writes a size_t to the logger based on current status. Only done in windows, as GCC complains. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, size_t value ); + #endif + + /*! + * @brief Writes long unsigned int to the logger based on current status. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, unsigned int value ); + + /*! + * @brief Writes int to the logger based on current status. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, int value ); + + /*! + * @brief Writes float to the logger based on current status. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, float value ); + + /*! + * @brief Writes double to the logger based on current status. + * + * @param logger A reference to a logger. + * @param value The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, double value ); + + /*! + * @brief Changes the message status of the logger + * + * @param logger A reference to a logger. + * @param type The value to write. + * @returns A reference to the logger streamed to. + */ + friend MENGE_API Logger & operator<<( Logger & logger, Logger::LogType type ); + + protected: + /*! + * @brief Writes the html header information to the given file. + */ + void writeHeader(); + + /*! + * @brief Writes the html tail information to the given file. + */ + void writeTail(); + + /*! + * @brief Process text. + * + * Modifies the string in place to make an html version of the text if the output + * file is valid, otherwise, simply returns leaving the string untouched. + * + * @param input The input text to write to the log. The string + */ + void processText( std::string & input ); + + /*! + * @brief Indicates if the output file is valid. + */ + bool _validFile; + + /*! + * @brief The file object for the html to be written to. + */ + std::ofstream _file; + + /*! + * @brief The current message type + */ + LogType _streamType; + }; + + + /*! + * @brief Globally available Logger + * + * The single, globally availably logger. This allows core files + * and plugins to use a single consistant logger object. + */ + extern MENGE_API Logger logger; + +} // namespace Menge + +#endif // __LOGGER_H__ diff --git a/src/Menge/MengeCore/Runtime/ReadersWriterLock.cpp b/src/Menge/MengeCore/Runtime/ReadersWriterLock.cpp new file mode 100644 index 00000000..63e85609 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/ReadersWriterLock.cpp @@ -0,0 +1,149 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ReadersWriterLock.h" +#include + +namespace Menge { + +///////////////////////////////////////////////////////////////////// +// Implementation of ReadersWriterLock +///////////////////////////////////////////////////////////////////// + +// NOTE: This implemenation is naively simple. +// OpenMP does not allow for sophisticated readers-writer locks. It contains +// no semaphores. So, this implementation simply serializes ALL reads and +// writes. Not optimal, but safe. +// +// TODO: Update this implementation when the threading paradigm is changed to +// support more sophisticated constructs. + + #ifdef _OPENMP + + ReadersWriterLock::ReadersWriterLock() { + omp_init_lock( &_lock ); + } + + /////////////////////////////////////////////////////////////////////// + + ReadersWriterLock::~ReadersWriterLock() { + omp_destroy_lock( &_lock ); + } + + /////////////////////////////////////////////////////////////////////// + + // NOTE: The code below is left in place, commented out, to facilitate debugging + // of future concurrency issues. + void ReadersWriterLock::lockRead() const { + //#pragma omp critical( READER_LOCK ) + //{ + //std::cout << "READ LOCK( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + //} + omp_set_lock( &_lock ); + //#pragma omp critical( READER_LOCK ) + // { + // std::cout << "\t READ LOCKED( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + // } + } + + /////////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::releaseRead() const { + //#pragma omp critical( READER_LOCK ) + //{ + //std::cout << "READ RELEASE( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + //} + omp_unset_lock( &_lock ); + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::lockWrite() const { + //#pragma omp critical( READER_LOCK ) + //{ + //std::cout << "WRITE LOCK( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + //} + omp_set_lock( &_lock ); + //#pragma omp critical( READER_LOCK ) + // { + // std::cout << "\t WRITE LOCKED( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + // } + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::releaseWrite() const { + //#pragma omp critical( READER_LOCK ) + //{ + //std::cout << "WRITE RELEASE( " << ((size_t)this) << ") - " << omp_get_thread_num() << "\n"; + //} + omp_unset_lock( &_lock ); + } + + #else // _OPENMP + + ReadersWriterLock::ReadersWriterLock() { + } + + ///////////////////////////////////////////////////////////////////// + + ReadersWriterLock::~ReadersWriterLock() { + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::lockRead() const { + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::releaseRead() const { + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::lockWrite() const { + } + + ///////////////////////////////////////////////////////////////////// + + void ReadersWriterLock::releaseWrite() const { + } + +#endif // _OPENMP +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/ReadersWriterLock.h b/src/Menge/MengeCore/Runtime/ReadersWriterLock.h new file mode 100644 index 00000000..b17c78d9 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/ReadersWriterLock.h @@ -0,0 +1,114 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ReadersWriterLock.h + * @brief The definition of a readers-writer lock + */ + +#ifndef __READERS_WRITER_LOCK_H__ +#define __READERS_WRITER_LOCK_H__ + +#include "CoreConfig.h" +#ifdef _OPENMP +#include +#endif + +namespace Menge { + + /*! + * @brief The definition of a readers-writer lock. + * + * A readers-writer lock can be used to secure a resource for concurrent + * usage such that multiple readers can safely utilize the resource but + * writing tasks must have sole access. + * + */ + class MENGE_API ReadersWriterLock { + public: + /*! + * @brief Constructor. + */ + ReadersWriterLock(); + + /*! + * @brief Destructor. + */ + virtual ~ReadersWriterLock(); + + /*! + * @brief Requests access to read a resource. When this function + * returns, the resource will be safe to read. + * The calling thread *must* call releaseRead otherwise + * deadlocks may occur. + */ + void lockRead() const; + + /*! + * @brief Releases the lock for reading. This must only be called + * by threads which had previously successfully called lockRead. + */ + void releaseRead() const; + + /*! + * @brief Requests access to write a resource. When this function + * returns, the resource will be safe to write. + * The calling thread *must* call releaseWrite otherwise + * deadlocks *will* occur. + */ + void lockWrite() const; + + /*! + * @brief Releases the lock for writing. This must only be called + * by threads which had previously successfully called lockWrite. + */ + void releaseWrite() const; + + #ifdef _OPENMP + private: + /*! + * @brief The openmp lock used for synchronization. + * + * This is mutable so the corresponding functions can be called in a const + * context. + */ + mutable omp_lock_t _lock; + #endif // _OPENMP + }; +} // namespace Menge +#endif diff --git a/src/Menge/MengeCore/Runtime/SimSystem.cpp b/src/Menge/MengeCore/Runtime/SimSystem.cpp new file mode 100644 index 00000000..7352c1bf --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimSystem.cpp @@ -0,0 +1,220 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimSystem.h" +// SceneGraph +#include "GLScene.h" +// MengeBase +#include "SimulatorInterface.h" +#include "SpatialQueries/SpatialQuery.h" +#include "Obstacle.h" +#include "SCBWriter.h" +// MengeRuntime +#include "VisAgent.h" +#include "VisObstacle.h" +// BFSM +#include "FSM.h" +// STL +#include + +namespace Menge { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of SimSystem + //////////////////////////////////////////////////////////////////////////// + + SimSystem::SimSystem( bool visualize ): SceneGraph::System(), _forVis(visualize), _sim(0x0), _fsm(0x0), _scbWriter(0x0),_lastUpdate(0.f), _isRunning(true), _maxDuration(100.f) { + } + + //////////////////////////////////////////////////////////////////////////// + + SimSystem::SimSystem( bool visualize, float duration ): SceneGraph::System(), _forVis(visualize), _sim(0x0), _fsm(0x0), _scbWriter(0x0),_lastUpdate(0.f), _isRunning(true), _maxDuration(duration) { + } + + //////////////////////////////////////////////////////////////////////////// + + SimSystem::~SimSystem() { + if ( _sim ) delete _sim; + if ( _fsm ) delete _fsm; + if ( _scbWriter ) delete _scbWriter; + } + + //////////////////////////////////////////////////////////////////////////// + + bool SimSystem::updateScene( float time ) { + const int agtCount = static_cast( _sim->getNumAgents() ); + if ( _isRunning ) { + if ( _scbWriter ) _scbWriter->writeFrame( _fsm ); + _lastUpdate = _sim->getGlobalTime(); + if ( _lastUpdate > _maxDuration ) { + _isRunning = false; + } else { + for ( size_t i = 0; i <= _sim->getSubSteps(); ++i ) { + try { + _isRunning = !_fsm->doStep(); + } catch ( BFSM::FSMFatalException & e ) { + logger << Logger::ERR_MSG << "Error in updating the finite state machine -- stopping!\n"; + logger << "\t" << e.what() << "\n"; + throw SceneGraph::SystemStopException(); + } + + _sim->doStep(); + if ( _forVis ) { + updateAgentPosition( agtCount ); + } + try { + _fsm->doTasks(); + } catch ( BFSM::FSMFatalException &e ) { + logger << Logger::ERR_MSG << e.what() << "\n"; + throw SceneGraph::SystemStopException(); + } + } + } + } + if ( !_isRunning ) { + // TODO: WHy is this here?? + throw SceneGraph::SystemStopException(); + return false; + } + return true; + } + + //////////////////////////////////////////////////////////////////////////// + + bool SimSystem::isFinished() const { + return _fsm->allFinal(); + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::setSimulator( Agents::SimulatorInterface * sim, BFSM::FSM * fsm ) { + if ( _sim ) { + std::string msg( "Simulator already assigned to SimSystem" ); + throw SimSystemFatalException( msg ); + } + _sim = sim; + _fsm = fsm; + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::setSimulator( Agents::SimulatorInterface * sim, BFSM::FSM * fsm, const std::string & outFileName, const std::string & scbVersion ) { + setSimulator( sim, fsm ); + try { + _scbWriter = new Agents::SCBWriter( outFileName, scbVersion, sim ); + } catch ( Agents::SCBFileException ) { + std::string msg( "Unable to create SCB file: "); + msg += outFileName; + throw SimSystemFatalException( msg ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::addObstacleToScene( SceneGraph::GLScene * scene ) { + // TODO: If the bsptree (ObstacleKDTree.h) chops up the obstacles, this isn't doing the + // right thing. Currently, the bsptree chops them + // THIS IS A HACK to address the issues of the ObstacleKDTree + // The right thing to do is modify things so that they are not chopped up. + std::set< const Agents::Obstacle * > handled; + const std::vector< Agents::Obstacle * > & obstacles = _sim->getSpatialQuery()->getObstacles(); + for ( size_t o = 0; o < obstacles.size(); ++o ) { + + const Agents::Obstacle * obst = obstacles[ o ]; + if ( handled.find( obst ) == handled.end() ) { + Vector2 p0a = obst->getP0(); + Vector2 p1a = obst->getP1(); + const Agents::Obstacle * next = obst->_nextObstacle; + while ( next && next->_unitDir * obst->_unitDir >= 0.99999f ) { + handled.insert( next ); + p1a.set( next->getP1() ); + next = next->_nextObstacle; + } + Vector3 p0( p0a.x(), _sim->getElevation( p0a ), p0a.y() ); + Vector3 p1( p1a.x(), _sim->getElevation( p1a ), p1a.y() ); + VisObstacle * vo = new VisObstacle( p0, p1 ); + + scene->addNode( vo ); + handled.insert( obst ); + } + } + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::addAgentsToScene( SceneGraph::GLScene * scene ) { + _visAgents = new VisAgent * [ _sim->getNumAgents() ]; + for ( size_t a = 0; a < _sim->getNumAgents(); ++a ) { + Agents::BaseAgent * agt = _sim->getAgent( a ); + VisAgent * agtNode = new VisAgent( agt ); + float h = _sim->getElevation( agt ); + agtNode->setPosition( agt->_pos.x(), h, agt->_pos.y() ); + scene->addNode( agtNode ); + _visAgents[ a ] = agtNode; + } + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::populateScene( SceneGraph::GLScene * scene ) { + assert( _sim != 0x0 && "Can't add SimSystem to scene when no simulator is connected" ); + + addAgentsToScene( scene ); + addObstacleToScene( scene ); + } + + //////////////////////////////////////////////////////////////////////////// + + void SimSystem::updateAgentPosition( int agtCount ) { + #pragma omp parallel for + for ( int a = 0; a < agtCount; ++a ) { + const Agents::BaseAgent * agt = _visAgents[ a ]->getAgent(); + float h = _sim->getElevation( agt ); + _visAgents[ a ]->setPosition( agt->_pos.x(), h, agt->_pos.y() ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + size_t SimSystem::getAgentCount() const { + return _sim->getNumAgents(); + } + + //////////////////////////////////////////////////////////////////////////// + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/SimSystem.h b/src/Menge/MengeCore/Runtime/SimSystem.h new file mode 100644 index 00000000..3347cdd7 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimSystem.h @@ -0,0 +1,292 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimSystem.h + * @brief The system which runs the simulation, coordinating + * the FSM and simulator. + */ + +#ifndef __SIM_SYSTEM_H__ +#define __SIM_SYSTEM_H__ + +// Scene graph +#include "System.h" +#include "MengeException.h" + +namespace Menge { + + // forward declarations + class VisAgent; + + namespace Agents { + class SimulatorInterface; + class SCBWriter; + } + + namespace SceneGraph { + class GLScene; + } + + namespace BFSM { + class FSM; + } + + // Exceptions for the system + /*! + * @brief Generic exception for the SimSystem. + */ + class MENGE_API SimSystemException : public virtual Menge::MengeException { + public: + /*! + * @brief Default constructor. + */ + SimSystemException() : Menge::MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SimSystemException( const std::string & s ): Menge::MengeException(s) {} + }; + + /*! + * @brief The fatal SimSystem exception. + */ + class MENGE_API SimSystemFatalException : public SimSystemException, public Menge::MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + SimSystemFatalException() : Menge::MengeException(), SimSystemException(), Menge::MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SimSystemFatalException( const std::string & s ): Menge::MengeException(s), SimSystemException(), Menge::MengeFatalException() {} + }; + + + /*! + * @brief Templated class for performing simulation. + * + * The SimSystem is the main mechanism which performs the simulation loop. + * It is responsible for updating the simulation step after step, with + * appropriate calls to the BFSM and the simulator. + */ + class MENGE_API SimSystem : public SceneGraph::System { + public: + + /*! + * @brief Constructor + * + * @param visualize True if the SimSystem will be connected to + * a visualizer (such as a Vis::GLViewer). + */ + SimSystem( bool visualize ); + + /*! + * @brief Constructor with duration limit + * + * @param visualize True if the SimSystem will be connected to + * a visualizer (such as a Vis::GLViewer). + * @param duration The maximum duration (in simulation time) + * the system will run. + */ + SimSystem( bool visualize, float duration ); + + /*! + * @brief Destructor. + */ + ~SimSystem(); + + /*! + * @brief Sets the maximum length allowed for the simulation to run. + * + * @param duration The maximum duration of the simulation + * (in simulation time). After this time has + * elapsed, the system no longer updates. + */ + inline void setMaxDuration( float duration ) {_maxDuration = duration; } + + /*! + * @brief Update the simulation (and possibly visual elements) to the + * given global time. + * + * @param time The global time of the system. + * @returns True if the system has changed such that it requires a redraw. + */ + virtual bool updateScene( float time ); + + /*! + * @brief Reports if the SimSystem is finished updating. + * + * @returns True if the system will no longer update. False if still + * willing to evalute. + */ + bool isFinished() const; + + /*! + * @brief Set the simulator and corresponding FSM for the simulator. + * + * This assumes that no output file (scb file) will be written. + * Once the simulator and finite state machine have been given to the SimSystem, + * the SimSystem is repsonsible for managing the memory (i.e. freeing up the memory.) + * + * Throws a SimSystemStateException if the simulator/fsm can't be set. + * It remains the responsibility of the caller to delete the sim and fsm in this case. + * + * @param sim A pointer to the simulator. + * @param fsm A pointer to the behavior finite state machine. + * @throws SimSystemFatalException If there is an error in assigning the simulator. + */ + void setSimulator( Agents::SimulatorInterface * sim, BFSM::FSM * fsm ); + + // Sets the simulator/fsm for the visualizer - prepares an scb file for writing (with the provided version) + /*! + * @brief Set the simulator and corresponding FSM for the simulator. + * + * This is used if an output file (scb file) *is* to be written. + * Once the simulator and finite state machine have been given to the SimSystem, + * the SimSystem is repsonsible for managing the memory (i.e. freeing up the memory.) + * + * Throws a SimSystemStateException if the simulator/fsm can't be set. + * It remains the responsibility of the caller to delete the sim and fsm in this case. + * + * @param sim A pointer to the simulator. + * @param fsm A pointer to the behavior finite state machine. + * @param outFileName The name of the scb file to write. + * @param scbVersion The version of scb file to write. + * @throws SimSystemFatalException If there is an error in assigning the simulator, or in + * initializing the output file. + */ + void setSimulator( Agents::SimulatorInterface * sim, BFSM::FSM * fsm, const std::string & outFileName, const std::string & scbVersion ); + + /*! + * @brief Add visual representations of the simulation obstcles to the GLScene. + * + * @param scene The scene which receives nodes for drawing obstacles. + */ + void addObstacleToScene( SceneGraph::GLScene * scene ); + + /*! + * @brief Add visual representations of the simulation agents to the GLScene. + * + * @param scene The scene which receives nodes for drawing agents. + */ + virtual void addAgentsToScene( SceneGraph::GLScene * scene ); + + /*! + * @brief Add visual representations of obstacles and agents to the GLScene. + * + * @param scene The scene which receives nodes for drawing agents. + */ + void populateScene( SceneGraph::GLScene * scene ); + + + /*! + * @brief Update the position of the *visual* agents from the simulation data. + * + * @param agtCount The number of agents in the system. + */ + virtual void updateAgentPosition( int agtCount ); + + /*! + * @brief Returns a pointer to the visualization agents + * + * @returns Returns the pointer to the pointers. + */ + inline VisAgent ** getVisAgents() { return _visAgents; } + + /*! + * @brief Reports the number of agents. + * + * @returns The number of VisAgents updated by the system. + */ + size_t getAgentCount() const; + + protected: + + /*! + * @brief Determines if the system is actually for driving + * a visual scene. + */ + bool _forVis; + + /*! + * @brief Simulator to run and (possibly) visualize. + */ + Agents::SimulatorInterface * _sim; + + /*! + * @brief The visualization agents the system is responsible + * for updating. + */ + VisAgent ** _visAgents; + + /*! + * @brief The behavior finite state machine for the simulator. + */ + BFSM::FSM * _fsm; + + /*! + * @brief The optional scb writer (if an output file has been + * successfully specified. + */ + Agents::SCBWriter * _scbWriter; + + /*! + * @brief The global time of last system update. + */ + float _lastUpdate; + + /*! + * @brief Indicates if the simulation is running. + */ + bool _isRunning; + + /*! + * @brief Maximum length of simulation time to compute (in simulation time). + */ + float _maxDuration; + }; +} // namespace Menge +#endif // __VIS_RVO_SIM_H__ diff --git a/src/Menge/MengeCore/Runtime/SimpleLock.cpp b/src/Menge/MengeCore/Runtime/SimpleLock.cpp new file mode 100644 index 00000000..1d1de223 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimpleLock.cpp @@ -0,0 +1,95 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimpleLock.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of SimpleLock + ///////////////////////////////////////////////////////////////////// + + // TODO: Update this implementation when the threading paradigm is changed to + // support more sophisticated constructs. + + #ifdef _OPENMP + + SimpleLock::SimpleLock() { + omp_init_lock( &_lock ); + } + + ///////////////////////////////////////////////////////////////////// + + SimpleLock::~SimpleLock() { + omp_destroy_lock( &_lock ); + } + + ///////////////////////////////////////////////////////////////////// + + void SimpleLock::lock() const { + omp_set_lock( &_lock ); + } + + ///////////////////////////////////////////////////////////////////// + + void SimpleLock::release() const { + omp_unset_lock( &_lock ); + } + + #else // _OPENMP + + SimpleLock::SimpleLock() { + } + + ///////////////////////////////////////////////////////////////////// + + SimpleLock::~SimpleLock() { + } + + ///////////////////////////////////////////////////////////////////// + + void SimpleLock::lock() const { + } + + ///////////////////////////////////////////////////////////////////// + + void SimpleLock::release() const { + } + + #endif // _OPENMP +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/SimpleLock.h b/src/Menge/MengeCore/Runtime/SimpleLock.h new file mode 100644 index 00000000..1eb32829 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimpleLock.h @@ -0,0 +1,101 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimpleLock.h + * @brief The definition of a simple thrading lock + */ + +#ifndef __SIMPLE_LOCK_H__ +#define __SIMPLE_LOCK_H__ + +#include "CoreConfig.h" +#ifdef _OPENMP +#include +#endif + +namespace Menge { + + /*! + * @brief The definition of a simple mutex-style lock. + * + * This lock provides a simple mutex to guarantee thread-safe concurrency. + * Use of this lock guarantees that only one thread at a time can acquire + * the lock. + * + */ + class MENGE_API SimpleLock { + public: + /*! + * @brief Constructor. + */ + SimpleLock(); + + /*! + * @brief Destructor. + */ + virtual ~SimpleLock(); + + /*! + * @brief Requests access to the mutex. When this function + * returns, the lock will be uniquely acquired by the calling thread. + * The calling thread *must* call release otherwise + * deadlocks may occur. + */ + void lock() const; + + /*! + * @brief Releases the acquired lock. This must only be called + * by the thread which had previously successfully called lock. + */ + void release() const; + + #ifdef _OPENMP + private: + /*! + * @brief The openmp lock used for synchronization. + * + * This is mutable so the corresponding functions can be called in a const + * context. + */ + mutable omp_lock_t _lock; + #endif // _OPENMP + + }; +} // namespace Menge +#endif // __SIMPLE_LOCK_H__ diff --git a/src/Menge/MengeCore/Runtime/SimulatorDB.cpp b/src/Menge/MengeCore/Runtime/SimulatorDB.cpp new file mode 100644 index 00000000..d024b3e6 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimulatorDB.cpp @@ -0,0 +1,146 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimulatorDB.h" +#include "SimulatorDBEntry.h" +#include "Logger.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of SimulatorDB + ///////////////////////////////////////////////////////////////////////////// + + SimulatorDB::SimulatorDB() { + // TODO: Add explicit initialization of STATIC pedestrian models + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string SimulatorDB::paramList() const { + ::std::string fmtList; + size_t i = 0; + const EntryList & eList = _entries; + const size_t COUNT = eList.size(); + EntryList::const_iterator itr = eList.begin(); + for ( ; itr != eList.end(); ++itr, ++i ) { + if ( i == 0 ) { + // beginning of list + fmtList = (*itr)->commandLineName(); + } else if ( i < COUNT - 1 ) { + // middle of list + fmtList += ", " + (*itr)->commandLineName(); + } else if ( i == COUNT - 1 ) { + if ( COUNT > 2 ) { + fmtList += ", "; + } + fmtList += "and " + (*itr)->commandLineName(); + } + } + return fmtList; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string SimulatorDB::briefDescriptions() const { + ::std::stringstream ss; + ss << "Available pedestrian models:\n"; + const EntryList & eList = _entries; + EntryList::const_iterator itr = eList.begin(); + for ( ; itr != eList.end(); ++itr ) { + ss << "\n\tParameter: " << (*itr)->commandLineName() << "\n"; + ss << "\t\t" << (*itr)->briefDescription(); + } + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string SimulatorDB::longDescriptions() const { + ::std::stringstream ss; + ss << "Available pedestrian models:\n"; + const EntryList & eList = _entries; + EntryList::const_iterator itr = eList.begin(); + for ( ; itr != eList.end(); ++itr ) { + ss << "\n\t---------------------------------------------------------\n"; + ss << "\tParameter: " << (*itr)->commandLineName() << "\n"; + ss << "\t" << (*itr)->longDescription() << "\n"; + } + return ss.str(); + } + + ///////////////////////////////////////////////////////////////////////////// + + SimulatorDBEntry * SimulatorDB::getDBEntry( const std::string & modelName ) { + std::string name( modelName ); + std::transform( name.begin(), name.end(), name.begin(), ::tolower ); + EntryList & eList = _entries; + EntryList::const_iterator itr = eList.begin(); + for ( ; itr != eList.end(); ++itr ) { + std::string testName = (*itr)->commandLineName(); + std::transform( testName.begin(), testName.end(), testName.begin(), ::tolower ); + if ( modelName == testName ) { + return *itr; + } + } + return 0x0; + } + + ///////////////////////////////////////////////////////////////////////////// + + SimulatorDBEntry * SimulatorDB::registerEntry( SimulatorDBEntry * entry ) { + std::string entryName = entry->commandLineName(); + EntryList & eList = _entries; + EntryList::const_iterator itr = eList.begin(); + for ( ; itr != eList.end(); ++itr ) { + std::string name = (*itr)->commandLineName(); + std::transform( name.begin(), name.end(), name.begin(), ::tolower ); + if ( entryName == name ) { + logger << Logger::ERR_MSG << "Failed to register a pedestrian model\n" \ + "\tIt's command-line parameter name (" << name << ") matches the name\n" \ + "\tof a previously registered pedestrian model.\n" \ + "\tThe database entry, " << typeid( entry ).name() << ", will not be registered.\n"; + delete entry; // TODO: DBEntries should probably be "destroyed" and not deleted. + return 0x0; + } + } + eList.push_back( entry ); + return entry; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/SimulatorDB.h b/src/Menge/MengeCore/Runtime/SimulatorDB.h new file mode 100644 index 00000000..067f7c2d --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimulatorDB.h @@ -0,0 +1,198 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimulatorDB.h + * @brief Central database for querying available pedestrian models. + * + * The SimulatorDB provides the mechanism by which new simulation models + * can easily be registered and their run-time properties queried by the + * main program. + */ + +#ifndef __SIMULATOR_DB_H__ +#define __SIMULATOR_DB_H__ + +#include "SimulatorDBEntry.h" +#include "CoreConfig.h" +#include "MengeException.h" +#include +#include +#include +#ifndef _WIN32 +#include +#endif + +namespace Menge { + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Exception for SimulatorDB issues. + */ + class MENGE_API SimDBException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + SimDBException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SimDBException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal SimulatorDB exception. + */ + class MENGE_API SimDBFatalException : public SimDBException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + SimDBFatalException() : MengeException(), SimDBException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + SimDBFatalException( const std::string & s ): MengeException(s), SimDBException(), MengeFatalException() {} + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A list of database entries. + */ + typedef std::list< SimulatorDBEntry * > EntryList; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The simulator database class. + * + * The main executable program relies on the simulator database to + * know what models are available for simulation. Furthermore, it + * uses the database to instantiate the appropriate types as well. + */ + class MENGE_API SimulatorDB { + public: + /*! + * @brief Constructor. + */ + SimulatorDB(); + + /*! + * @brief Destructor. + */ + ~SimulatorDB(){} + + /*! + * @brief Reports the number of registered pedestrian models. + * + * @returns The number of pedestrian models. + */ + inline size_t modelCount() const { return _entries.size(); } + + /*! + * @brief Gets a formatted list of valid command-line + * parameters for all registered simulators. + * + * @returns A formatted list of all registered simulators' + * command-line parameter names, + * e.g., model1, model2, ..., and modelN. + */ + ::std::string paramList() const; + + /*! + * @brief Formats all brief descriptions into a single + * string. + * + * @returns A formatted string consisting of all model's and + * their brief descriptions. + */ + ::std::string briefDescriptions() const; + + /*! + * @brief Formats all long descriptions into a single + * string. + * + * @returns A formatted string consisting of all model's and + * their long descriptions. + */ + ::std::string longDescriptions() const; + + /*! + * @brief Returns the database entry for the given command line parameter. + * + * It returns the database entry with a command line parameter value that is the + * same as the provided string. The test is case insensitive. + * + * @param modelName The command-line parameter for the desired pedestrian model. + * @returns A pointer to the summary entity. If the name does not match + * a registered model, NULL is returned + */ + SimulatorDBEntry * getDBEntry( const std::string & modelName ); + + /*! + * @brief Registers a database entry. + * + * The registration is only valid if the entry's commandLineName is unique + * (see SimulatorDBEntry::commandLineName). If the given entry + * duplicates a previous entry, the pointer is deleted. + * + * @param entry A pointer to the entry to register. + * @returns The same pointer (if valid, null if invalid). + */ + SimulatorDBEntry * registerEntry( SimulatorDBEntry * entry ); + + private: + /*! + * @brief Returns the static list of entries. + * + * This is part of C++ voodoo to make static registration of pedestrian + * models possible and "easy". + */ + EntryList _entries; + }; +} // namespace Menge +#endif // __SIMULATOR_DB_H__ diff --git a/src/Menge/MengeCore/Runtime/SimulatorDBEntry.cpp b/src/Menge/MengeCore/Runtime/SimulatorDBEntry.cpp new file mode 100644 index 00000000..d79199ce --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimulatorDBEntry.cpp @@ -0,0 +1,227 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "SimulatorDBEntry.h" +// Menge Runtime +#include "SimSystem.h" +#include "BaseAgentContext.h" +#include "Logger.h" +// Agents +#include "AgentInitializer.h" +#include "SimulatorInterface.h" +// BFSM +#include "FSMDescrip.h" +#include "FSM.h" +// SceneGraph +#include "GLScene.h" +#include "MengeException.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of SimulatorDBEntry + //////////////////////////////////////////////////////////////////////////// + + SimSystem * SimulatorDBEntry::createSimSystem( bool visualize, float duration ) { + return new SimSystem( visualize, duration ); + } + + //////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * SimulatorDBEntry::initSimulator( const std::string & sceneFileName, bool VERBOSE ) { + Agents::SimulatorInterface * sim = getNewSimulator(); + Agents::AgentInitializer * agentInit = getAgentInitalizer(); + Agents::SimXMLLoader loader( sim ); + logger.line(); + if ( ! loader.loadFromXML( sceneFileName, agentInit, VERBOSE ) ) { + logger << Logger::ERR_MSG << "Couldn't initialize scene from xml."; + return 0x0; + } + return sim; + } + + //////////////////////////////////////////////////////////////////////////// + + BFSM::FSM * SimulatorDBEntry::initFSM( const std::string & behaveFile, Agents::SimulatorInterface * sim, bool VERBOSE ) { + logger.line(); + BFSM::FSMDescrip fsmDescrip; + + if ( ! fsmDescrip.loadFromXML( behaveFile, VERBOSE ) ) { + logger << Logger::ERR_MSG << "Problems loading behavior specification!"; + return 0x0; + } + if ( VERBOSE ) logger << fsmDescrip << "\n"; + + BFSM::FSM * fsm = BFSM::buildFSM( fsmDescrip, sim, VERBOSE ); + if ( !fsm ) { + logger << Logger::ERR_MSG << "Error instantiating FSM from description."; + } + return fsm; + } + + //////////////////////////////////////////////////////////////////////////// + + bool SimulatorDBEntry::finalize( Agents::SimulatorInterface * sim, BFSM::FSM * fsm ) { + // older versions of OpenMP require signed for loop counters + int agtCount = (int)sim->getNumAgents(); + #pragma omp parallel for + for ( int a = 0; a < agtCount; ++a ) { + Agents::BaseAgent * agt = sim->getAgent( a ); + fsm->computePrefVelocity( agt ); + } + try { + sim->finalize(); + } catch ( Menge::MengeException & e ) { + logger << Logger::ERR_MSG << "Problem in finalizing the simulator.\n"; + logger << "\t" << e.what() ; + delete fsm; + return false; + } + try { + fsm->finalize(); + } catch ( Menge::MengeFatalException & e ) { + logger << Logger::ERR_MSG << "Fatal error finalizing the finite state machine!\n"; + logger << "\t" << e.what(); + delete fsm; + return false; + } catch ( Menge::MengeException & e ) { + logger << Logger::WARN_MSG << "There were non-fatal errors in finalizing the finite state machine!\n"; + logger << "\t" << e.what(); + } + return true; + } + + //////////////////////////////////////////////////////////////////////////// + + SimSystem * SimulatorDBEntry::getSimulatorSystem( size_t & agentCount, + float & simTimeStep, + size_t subSteps, + float simDuration, + const std::string & behaveFile, + const std::string & sceneFile, + const std::string & outFile, + const std::string & scbVersion, + bool visualize, + bool VERBOSE ) + { + + _sim = initSimulator( sceneFile, VERBOSE ); + if ( !_sim ) { + return 0x0; + } + // TODO: Remove time step from the simulator specification! + float specTimeStep = _sim->getTimeStep(); + + _fsm = initFSM( behaveFile, _sim, VERBOSE ); + if ( !_fsm ) { + return 0x0; + } + if ( !finalize( _sim, _fsm ) ) { + return 0x0; + } + + if ( simTimeStep > 0.f ) { + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "Simulation time step set by command-line argument: " << simTimeStep << "."; + } + _sim->setTimeStep( simTimeStep ); + } else { + simTimeStep = specTimeStep; + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "Simulation time step set by specification file: " << specTimeStep << "."; + } + } + _sim->setSubSteps( subSteps ); + float effTimeStep = simTimeStep / ( 1.f + subSteps ); + logger << Logger::INFO_MSG << "For logical time step: " << simTimeStep << " and " << subSteps << " sub step"; + if ( subSteps !=1 ) { + logger << "s"; + } + logger << ", effective time step is: " << effTimeStep; + + SimSystem * system = createSimSystem( visualize, simDuration ); + try { + if ( outFile != "" ) { + system->setSimulator( _sim, _fsm, outFile, scbVersion ); + } else { + system->setSimulator( _sim, _fsm ); + } + } catch ( SimSystemFatalException & e ) { + logger << Logger::ERR_MSG << e.what(); + delete system; + delete _fsm; + delete _sim; + _sim = 0x0; + return 0x0; + } + agentCount = _sim->getNumAgents(); + return system; + } + + //////////////////////////////////////////////////////////////////////////// + + void SimulatorDBEntry::populateScene( SimSystem * system, SceneGraph::GLScene * scene ) { + system->populateScene( scene ); + } + + //////////////////////////////////////////////////////////////////////////// + + BaseAgentContext * SimulatorDBEntry::getAgentContext( SimSystem * simSystem ) { + BaseAgentContext * ctx = contextFromSystem( simSystem ); + if ( ctx ) ctx->setFSMContext( _fsm->getContext() ); + return ctx; + } + + //////////////////////////////////////////////////////////////////////////// + + float SimulatorDBEntry::simDuration() const { + return _sim != 0x0 ? _sim->getGlobalTime() : -1.f; + } + + //////////////////////////////////////////////////////////////////////////// + + BaseAgentContext * SimulatorDBEntry::contextFromSystem( SimSystem * simSystem ) { + return new BaseAgentContext( simSystem->getVisAgents(), simSystem->getAgentCount() ); + } + + //////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * SimulatorDBEntry::getAgentInitalizer() const { + return new Agents::AgentInitializer(); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/SimulatorDBEntry.h b/src/Menge/MengeCore/Runtime/SimulatorDBEntry.h new file mode 100644 index 00000000..9df90226 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/SimulatorDBEntry.h @@ -0,0 +1,300 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SimulatorDBEntry.h + * @brief Definition of an entry into the simulator database. + * + * This provides the mechanism by which the executable can learn about + * new pedestrian models/simulators without any significant code + * contortions. + */ + +#ifndef __SIMULATOR_DB_ENTRY_H__ +#define __SIMULATOR_DB_ENTRY_H__ + +#include +#include +#include "CoreConfig.h" + +namespace Menge { + + class SimSystem; + class BaseAgentContext; + namespace Agents { + class AgentInitializer; + class SimulatorInterface; + } + namespace SceneGraph { + class GLScene; + } + namespace BFSM { + class FSMDescrip; + class FSM; + } + + /*! + * @brief An entry in the simulator database. + * + * Every pedestrian model must define and register a SimulatorDBEntry. + * The entry provides brief and long descriptions of the pedestrian + * model to display in response to command-line queries. Furthermore, + * they are responsible for instantiating simulators, behavior FSM, + * and SimSystem (although, this is done in the base class and not + * the derived classes. + * + * A derived class should do the following: + * - Inherit from the SimulatorDBEntry + * - Implement the following functions: + * - SimulatorDBEntry::briefDescription + * - SimulatorDBEntry::longDescription + * - SimulatorDBEntry::viewName + * - SimulatorDBEntry::commandLineName + * - SimulatorDBEntry::getNewSimulator + * - Optionally implement the following functionsl + * - SimulatorDBEntry::contextFromSystem if the pedestrian model provides + * a unique sub-class of Agents::BaseAgentContext. + * - SimulatorDBEntry::getAgentInitalizer if the pedestrian model has + * custom per-agent attributes to parse (in addition to the common parameters). + */ + class MENGE_API SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const = 0; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const = 0; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual ::std::string viewerName() const = 0; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const = 0; + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator() = 0; + + /*! + * @brief Returns a simulator system that can be attached to a + * SceneGraph::GLScene and advanced by a Viewer. + * + * @param agentCount The number of the agents in the system. + * @param simTimeStep The simulator's time step (for updating the sim system). + * @param subSteps The number of computation sub-steps to take. + * @param simDuration The maximum duration to allow the simulation to run. + * @param behaveFile The full path to the xml behavior specification. + * @param sceneFile The full path to the xml scene specification. + * @param outFile The full path to the output file to write the agent + * trajectories. If the empty string, no output file will + * be written. + * @param scbVersion The scb version to write. + * @param visualize Determines if this simulator is to be visualized. + * @param VERBOSE Determines if the initialization process prints status + * and information to the console. True ouputs, false does not. + * @returns A pointer to the resultant System for running the simulation. + * If there is an error, NULL is returned. + */ + SimSystem * getSimulatorSystem( size_t & agentCount, + float & simTimeStep, + size_t subSteps, + float simDuration, + const std::string & behaveFile, + const std::string & sceneFile, + const std::string & outFile, + const std::string & scbVersion, + bool visualize, + bool VERBOSE ); + + /*! + * @brief Populates the given GLScene with visualization entities tracked + * in the system. + * + * @param system The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntry::getSimulatorSystem. + * @param scene The scene to populate with visual elements. + */ + void populateScene( SimSystem * system, SceneGraph::GLScene * scene ); + + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * @param system The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntry::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. + */ + BaseAgentContext * getAgentContext( SimSystem * system ); + + /*! + * @brief Reports the current run-time of an instantiated simulation. + * + * This is only meaningful if called *after* getSimulatorSystem. + * + * @returns The current run-time of the instantiated simulation. If no + * simulation has been instantiated, -1 is returned. + */ + float simDuration() const; + + protected: + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * If the provided system is not, in fact, a pointer to a SimSystem for the + * appropriate simulator type, this function will report failure. Furthermore, + * the default implementation is to return a BaseAgentContext. If the + * simulator comes with a novel context, this function should be overridden + * in the derived SimulatorDBEntry. + * + * @param simSystem The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntry::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. If the system is of + * the wrong type (or if there is any other problem), NULL is returned. + */ + virtual BaseAgentContext * contextFromSystem( SimSystem * simSystem ); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * Each derived database entry must provide the appropriate AgentInitializer + * for its simulator type, in order to fully process all of the corresponding + * XML data to initialize the agent population. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + + /*! + * @brief Creates the simulator. + * + * @param sceneFileName The full path to the simulation scene specification. + * @param VERBOSE Determines if the initialization outputs status + * and information to the console. True outputs, + * false remains silent. + * @returns A pointer to the instantiated simulator. + * If there is an error, NULL is returned. + */ + Agents::SimulatorInterface * initSimulator( const std::string & sceneFileName, bool VERBOSE ); + + /*! + * @brief Creates the finite state machine and finalizes simulator and fsm + * + * @param behaveFile string containing the full path to the behavior file + * @param sim pointer to the simulator interface to be used in conjunction with the FSM + * @param VERBOSE boolean flag for verbose output + * @returns A pointer to the instantiated finite state machine for the simulator. + * If there is an error, NULL is returned. + */ + BFSM::FSM * initFSM( const std::string & behaveFile, Agents::SimulatorInterface * sim, bool VERBOSE ); + + /*! + * @brief Finalizes the finite state machine and simulator in preparation for + * execution. + * + * @param sim A pointer to the simulator. + * @param fsm The finite state machine that goes with the simulator. + * @returns A boolean reporting if finalization was successful (true) or not (false). + */ + bool finalize( Agents::SimulatorInterface * sim, BFSM::FSM * fsm ); + + /*! + * @brief Creates an instance of a SimSystem to populate. + * + * This is the mechanism by which pedestrian plug-ins can override the behavior + * of the SimSystem based on models, by sub-classing the SimSystem and providing + * an alternative implementation. + * + * @param visualize True if the SimSystem will be connected to + * a visualizer (such as a Vis::GLViewer). + * @param duration The maximum duration (in simulation time) + * the system will run. + * @returns A pointer to a new SimSystem. + */ + virtual SimSystem * createSimSystem( bool visualize, float duration ); + + /*! + * @brief A pointer to the simulator. The database entry is not responsible for + * deleting it unless there is an error in initialization. + */ + Agents::SimulatorInterface * _sim; + + /*! + * @brief A pointer to the behavior finite state machine. The database entry is *not* + * responsible for deleting it unless there is an error in initialization. + */ + BFSM::FSM * _fsm; + }; +} // namespace Menge + +#endif // __SIMULATOR_DB_ENTRY_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/Utils.cpp b/src/Menge/MengeCore/Runtime/Utils.cpp new file mode 100644 index 00000000..3bb14e63 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/Utils.cpp @@ -0,0 +1,83 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Utils.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of Utilities + //////////////////////////////////////////////////////////////////////////// + + float toFloat( const std::string & value ) throw( UtilException ) { + float result; + std::stringstream ss( value, std::ios_base::in ); + ss >> result; + if ( ss.fail() ) { + throw UtilException(); + } + return result; + } + + //////////////////////////////////////////////////////////////////////////// + + int toInt( const std::string & value ) throw( UtilException ) { + int result; + std::stringstream ss( value, std::ios_base::in ); + ss >> result; + if ( ss.fail() ) { + throw UtilException(); + } + return result; + } + + //////////////////////////////////////////////////////////////////////////// + + size_t toSize_t( const std::string & value ) throw( UtilException ) { + size_t result; + std::stringstream ss( value, std::ios_base::in ); + ss >> result; + if ( ss.fail() || result < 0 ) { + throw UtilException(); + } + return result; + } + + //////////////////////////////////////////////////////////////////////////// +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/Utils.h b/src/Menge/MengeCore/Runtime/Utils.h new file mode 100644 index 00000000..32f00e6d --- /dev/null +++ b/src/Menge/MengeCore/Runtime/Utils.h @@ -0,0 +1,131 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Utils.h + * @brief A collection of convenience utilities. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include "CoreConfig.h" +#include "MengeException.h" +#include + +#if defined(_MSC_VER) + /*! + * This is visual studio non-ansi compliant functionality + * It doesnt like functions which declare specific types of exceptions thrown + * This turns off the silly visual studio warning. + */ + #pragma warning(disable:4290) +#endif + +namespace Menge { + + /*! + * @brief Exception thrown when a utility function fails.. + */ + class UtilException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + UtilException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + UtilException( const std::string & s ): MengeException(s) {} + + }; + + /*! + * @brief Exception thrown when the utility functions have an error which cannot be + * recovered from. + */ + class UtilFatalException : public UtilException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + UtilFatalException() : MengeException(), UtilException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + UtilFatalException( const std::string & s ): MengeException(s), UtilException(), MengeFatalException() {} + }; + + /*! + * @brief Converts a string to a float. + * + * @param value A string representing a float value. + * @throws A UtilException if the string is improperly formatted. + * @returns The float representation of the value held in the string. + */ + MENGE_API float toFloat( const std::string & value ) throw( UtilException ); + + + /*! + * @brief Converts a string to an int. + * + * @param value A string representing a int value. + * @throws A UtilException if the string is improperly formatted. + * @returns The int representation of the value held in the string. + */ + MENGE_API int toInt( const std::string & value ) throw( UtilException ); + + + + /*! + * @brief Converts a string to a size_t. + * + * @param value A string representing a size_t value. + * @throws A UtilException if the string is improperly formatted. + * @returns The size_t representation of the value held in the string. + */ + MENGE_API size_t toSize_t( const std::string & value ) throw( UtilException ); +} // namespace Menge + +#endif // __UTILS_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/VisAgent.cpp b/src/Menge/MengeCore/Runtime/VisAgent.cpp new file mode 100644 index 00000000..be9072f4 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/VisAgent.cpp @@ -0,0 +1,118 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VisAgent.h" +#include "BaseAgent.h" +#include "shapes.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of VisAgent + ///////////////////////////////////////////////////////////////////////////// + + VisAgent::VisAgent( Agents::BaseAgent * agent ):SceneGraph::GLNode(), SceneGraph::Selectable(), _agent(agent) { + const Vector2 & pos = _agent->_pos; + _pos.set( pos.x(), 0.f, pos.y() ); + } + + ///////////////////////////////////////////////////////////////////////////// + + void VisAgent::drawGL( bool select ) { + float r=0.5f, g=0.5f, b=0.5f; + if ( select ) { + loadSelectName(); + } else { + getColor( r, g, b ); + } + float radius = _agent->_radius; + glPushMatrix(); + glTranslatef( _pos.x(), _pos.y(), _pos.z() ); + SceneGraph::Cylinder::drawCylinder( radius, 1.72f, r, g, b, 1.f ); + + glPopMatrix(); + } + + /////////////////////////////////////////////////////////////////////////////// + + void VisAgent::getColor( float & r, float & g, float & b ) { + if ( _selected ) { + r = 1.f; + g = 1.f; + b = 1.f; + } else { + // TODO: this is bad. I only support six classes + // Ultimately, replace this with a class that determines colors based + // on arbitrary rules + size_t colorClass = _agent->_class % 6; + switch( colorClass ) { + case 0: + r = 0.9f; // red + g = 0.1f; + b = 0.1f; + break; + case 1: + r = 0.25f; // blue + g = 0.25f; + b = 0.9f; + break; + case 2: + r = 0.1f; // green + g = 0.9f; + b = 0.1f; + break; + case 3: + r = 0.9f; // orange-yellow + g = 0.75f; + b = 0.1f; + break; + case 4: + r = 0.25f; // cyan + g = 0.9f; + b = 0.9f; + break; + case 5: + r = 0.9f; // magenta + g = 0.1f; + b = 0.9f; + default: + break; + } + } + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/VisAgent.h b/src/Menge/MengeCore/Runtime/VisAgent.h new file mode 100644 index 00000000..4d40ae43 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/VisAgent.h @@ -0,0 +1,125 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VisAgent.h + * @brief Simple, cylindrical visualization for agents. + */ + +#ifndef __VIS_AGENT_H__ +#define __VIS_AGENT_H__ + +#include "CoreConfig.h" +#include "GLNode.h" +#include "Select.h" + +namespace Menge { + + // forward declaration + namespace Agents { + class BaseAgent; + } + + /*! + * @brief The basic agent visualization class: a selectable cylinder. + * + * This is the basic visualization of simulation agents in the visualization + * context. The agents are drawn as 3D cylinders by default. This class can + * be sub-classed adn the drawGL method can be overridden to provide a different + * visualization mechanism. + */ + class MENGE_API VisAgent : public SceneGraph::GLNode, public SceneGraph::Selectable { + public: + /*! + * @brief Constructor. + * + * @param agent The agent to be visualized. + */ + VisAgent( Agents::BaseAgent * agent ); + + /*! + * @brief Draw the agent into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void drawGL( bool select=false ); + + /*! + * @brief Returns a Agents::BaseAgent pointer of the associated simulation + * agent. + * + * @returns A pointer to the visualization agent's simulation agent. + */ + Agents::BaseAgent * getAgent() { return _agent; } + + /*! + * @brief Set the 3D position of the visual agent. + * + * @param x The x-position of the agent (in world coordinates). + * @param y The y-position of the agent (in world coordinates). + * @param z The z-position of the agent (in world coordinates). + */ + inline void setPosition( float x, float y, float z ) { _pos.set( x, y, z ); } + + protected: + /*! + * @brief Defines the color of the cylinder. + * + * The color is computed and returned via the three floats passed in as + * parameters. + * + * @param r The red component of the cylinder. + * @param g The green component of the cylinder. + * @param b The blue component of the cylinder. + */ + void getColor( float & r, float & g, float & b ); + + /*! + * @brief The logical agent being visualized. + */ + Agents::BaseAgent * _agent; + + /*! + * @brief The position in R3 of the logical agent. + */ + Vector3 _pos; + }; +} // namespace Menge + +#endif //__VIS_AGENT_H__ diff --git a/src/Menge/MengeCore/Runtime/VisObstacle.cpp b/src/Menge/MengeCore/Runtime/VisObstacle.cpp new file mode 100644 index 00000000..601c35db --- /dev/null +++ b/src/Menge/MengeCore/Runtime/VisObstacle.cpp @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VisObstacle.h" +#include "graphCommon.h" + +namespace Menge { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of VisObstacle + //////////////////////////////////////////////////////////////////////////// + + VisObstacle::VisObstacle( const Vector3 & p0, const Vector3 & p1 ): SceneGraph::GLNode(), _p0(p0), _p1(p1) { + } + + //////////////////////////////////////////////////////////////////////////// + + void VisObstacle::drawGL( bool select ) { + // TODO: remove this from here place it somewhere where it gets called upon + // context initialization + if ( !select ) { + glPushAttrib( GL_LINE_BIT | GL_ENABLE_BIT ); + glDisable( GL_LIGHTING ); + glLineWidth( 3.f ); + glColor3f( 0.75f, 0.75f, 0.75f ); + + //Vector2 p0 = _obst->getP0(); + //Vector2 p1 = _obst->getP1(); + glBegin( GL_LINES ); + glVertex3f( _p0.x(), _p0.y(), _p0.z() ); + glVertex3f( _p1.x(), _p1.y(), _p1.z() ); + glEnd(); + glPopMatrix(); + glPopAttrib(); + } + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/VisObstacle.h b/src/Menge/MengeCore/Runtime/VisObstacle.h new file mode 100644 index 00000000..8fffdcc9 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/VisObstacle.h @@ -0,0 +1,87 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __VIS_OBSTACLE_H__ +#define __VIS_OBSTACLE_H__ + +/*! + * @file VisObstacle.h + * @brief The node for visualizing a simulation obstacle. + */ +#include "CoreConfig.h" +#include "Math/Vector3.h" +#include "GLNode.h" + +namespace Menge { + using namespace Math; + + /*! + * @brief A simple class for drawing a simulation obstacle (line segment). + * The obstacle is drawn with lines in 3D space. + */ + class MENGE_API VisObstacle : public SceneGraph::GLNode { + public: + /*! + * @brief Constructor. + * + * @param p0 The first end point of the line segment. + * @param p1 The second end point of the line segment. + */ + VisObstacle( const Vector3 & p0, const Vector3 & p1 ); + + /*! + * @brief Draws the object into the OpenGL context. + * + * @param select Determines if the object is being drawn + * in a selection context (true) or visualization (false). + */ + void drawGL( bool select=false ); + + protected: + /*! + * @brief The line segment's first end point. + */ + Vector3 _p0; + + /*! + * @brief The line segment's second end point. + */ + Vector3 _p1; + }; +} // namespace Menge +#endif //__VIS_OBSTACLE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/os.cpp b/src/Menge/MengeCore/Runtime/os.cpp new file mode 100644 index 00000000..a29dcaa9 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/os.cpp @@ -0,0 +1,419 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "os.h" +#include "Logger.h" +#include +#include +#include +#include +#include +#include + +#ifndef _MSC_VER +#include +#include +#include +#include +#include +// For linux absolute path +#include +#include +#endif + +namespace Menge { + + namespace os { + bool listdir( const std::string & path, StringList & contents, const std::string & wildcard ) { + if ( ! path::exists( path ) ) { + logger << Logger::ERR_MSG << "Path does not exist: " << path << "\n"; + return false; + } + #ifdef _MSC_VER + WIN32_FIND_DATA FindFileData; + HANDLE hFind = INVALID_HANDLE_VALUE; + + std::string wildPath = path + path::pathSep() + wildcard; + hFind = FindFirstFile( wildPath.c_str(), &FindFileData); + + if( hFind == INVALID_HANDLE_VALUE ) { + logger << Logger::ERR_MSG << "No files in path: " << path << "\n"; + return false; + } + + std::string file = FindFileData.cFileName; + if ( file != "." && file != ".." ) { + contents.push_back( std::string( file ) ); + } + + + while(FindNextFile(hFind, &FindFileData) != 0) { + file = std::string( FindFileData.cFileName ); + if ( file != "." && file != ".." ) { + contents.push_back( file ); + } + } + + FindClose(hFind); + return true; + #else + DIR *dp; + struct dirent *dirp; + struct stat st; + + if ( ( dp = opendir( path.c_str() ) ) == NULL ) { + logger << Logger::ERR_MSG << "Error: invalid path\n"; + return false; + } + + while ( ( dirp = readdir( dp ) ) != NULL ) { + std::string name( dirp->d_name ); + std::string fullName = path + "/" + name; + + if ( name[0] == '.' ) continue; + + if ( stat( fullName.c_str(), &st ) == -1 ) continue; + + const bool isDirectory = ( st.st_mode & S_IFDIR ) != 0; + if ( isDirectory ) continue; + + // TODO: I need to use the wildcard + contents.push_back( name ); + + } + closedir( dp ); + return true; + #endif + + } + + /////////////////////////////////////////////////////////////////////////////////// + + FILE_SIZE fileSize( const std::string & path ) { + #ifdef _MSC_VER + WIN32_FIND_DATA FindFileData; + HANDLE hFind = INVALID_HANDLE_VALUE; + + hFind = FindFirstFile( path.c_str(), &FindFileData ); + if ( hFind != INVALID_HANDLE_VALUE ) { + return FindFileData.nFileSizeLow; + } else { + return 0; + } + FindClose(hFind); + return 0; + #else + + struct stat filestatus; + if (-1 != stat(path.c_str(), &filestatus)) { + return filestatus.st_size; + } else { + return 0; + } + + #endif + } + + /////////////////////////////////////////////////////////////////////////////////// + + std::string fileSizeStr( FILE_SIZE size ) { + static const char * SUFFIXES[] = { "b ", "Kb", "Mb", "Gb", "Tb", "Pb" }; + static const int MAX_SUF = 5; + int sIndex = 0; + double sz = size; + + while ( sz > 1000.0 ) { + sz /= 1000.0; + sIndex += 1; + } + std::stringstream ss; + ss.precision( 3 ); + if ( sIndex > MAX_SUF ) { + + ss << size << " b"; + } else { + ss << sz << " " << SUFFIXES[ sIndex ]; + } + return ss.str(); + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool remove( const std::string & path ) { + #ifdef _MSC_VER + return 0 == DeleteFile( path.c_str() ); + #else + return (0==remove ( path.c_str() )); + #endif + } + + /////////////////////////////////////////////////////////////////////////////////// + #ifdef _WIN32 + bool mkdir( const std::string & path ) { + BOOL retval = CreateDirectory( path.c_str(), 0x0 ); + if ( !retval ) { + DWORD err = GetLastError(); + if ( err == ERROR_ALREADY_EXISTS ) { + // This is a funny case -- it prints an error message bug reports true + // because the folder actually exists. + logger << Logger::ERR_MSG << "Cannot make directory. Path already exists: " << path << "\n"; + return true; + } else if ( err == ERROR_PATH_NOT_FOUND ) { + logger << Logger::ERR_MSG << "Cannot make directory. Intermediate directories missing: " << path << "\n"; + return false; + } + } + return true; + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool makedirs( const std::string & path ) { + + std::string fullpath; + path::absPath( path, fullpath ); + + if ( path::exists( fullpath ) ) { + return true; + } + + size_t pos = fullpath.find( path::pathSep() ); + while ( pos != std::string::npos ) { + std::string parent = fullpath.substr( 0, pos ); + if ( !path::exists( parent ) ) { + if ( ! mkdir( parent ) ) { + return false; + } + } + pos = fullpath.find( path::pathSep(), pos + 1 ); + } + return mkdir( fullpath ); + } + #else + + bool mkdir( const std::string & path ) { + return ::mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool makedirs( const std::string & path ) { + size_t err; + std::string fullpath; + path::absPath( path, fullpath ); + size_t pos = 0; + bool ret_val = true; + + while((ret_val == true || err == EEXIST) && pos != std::string::npos) + { + pos = fullpath.find(path::pathSep(), pos + 1); + ret_val = mkdir(fullpath.substr(0, pos)); + err = errno; + } + + return !ret_val; + + } + + + #endif + /////////////////////////////////////////////////////////////////////////////////// + + namespace path { + + /////////////////////////////////////////////////////////////////////////////////// + + bool absPath( const std::string & path, std::string & fullPath ) { + + const unsigned int BUFSIZE = 4096; + char BUFFER[ BUFSIZE ]; + + #ifdef _MSC_VER + + + char ** lppPart= {0x0}; + DWORD retval = GetFullPathName( path.c_str(), BUFSIZE, BUFFER, lppPart ); + + + #else + std::string storage; + std::string mutpath = path; + std::string mutpath2; + std::string splitStr; + bool iterative = false; + size_t err = 0; + + char * retval = realpath( path.c_str(), BUFFER ); + err = errno; + + if (retval == 0 && errno == ENOENT){ + + //split the path until we find a valid path + //base case + iterative = true; + split(path,mutpath,splitStr); + storage = splitStr; + retval = realpath( mutpath.c_str(), BUFFER ); + err = errno; + while (retval == 0 && errno == ENOENT){ + + //strip and split the string + split(mutpath,mutpath2,splitStr); + storage = join(2,splitStr.c_str(),storage.c_str()); + retval = realpath( mutpath2.c_str(), BUFFER ); + err = errno; + mutpath = mutpath2; + } + } + #endif + if (retval == 0){ + logger << Logger::ERR_MSG << "Invalid path: " << path << "\n"; + return false; + } else { + fullPath = std::string( BUFFER ); + #ifdef _MSC_VER + #else + if (iterative) + fullPath = join(2,fullPath.c_str(),storage.c_str()) ; + #endif + return true; + } + + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool isdir( const std::string & path ) { + + #ifdef _MSC_VER + DWORD attr = GetFileAttributes( path.c_str() ); + if ( attr == INVALID_FILE_ATTRIBUTES ) { + logger << Logger::ERR_MSG << "Invalid file: " << path << "\n"; + return false; + } else { + return (attr & FILE_ATTRIBUTE_DIRECTORY) > 0; + } + #else + struct stat s; + if (stat(path.c_str(), &s) == 0) { + if (s.st_mode & S_IFDIR) { + return true; + } else if (s.st_mode & S_IFREG) { + return false; + } else { + logger << Logger::ERR_MSG << "Invalid file: " << path << "\n"; + return false; + } + } + return false; + + #endif + } + + /////////////////////////////////////////////////////////////////////////////////// + + std::string join( unsigned int pathCount, ... ) { + if ( pathCount == 0 ) return ""; + + va_list arguments; + va_start ( arguments, pathCount ); + + if ( pathCount == 1 ) { + return va_arg( arguments, const char* ); + } else { + std::string fullPath = va_arg( arguments, const char* ); + for ( unsigned int i = 1; i < pathCount; ++i ) { + std::string level( va_arg( arguments, const char* ) ); + fullPath += pathSep() + level; + } + va_end( arguments ); + return fullPath; + } + + va_end ( arguments ); + return ""; + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool exists( const std::string & path ) { + #ifdef _MSC_VER + WIN32_FIND_DATA FindFileData; + HANDLE hFind = INVALID_HANDLE_VALUE; + + hFind = FindFirstFile( path.c_str(), &FindFileData ); + + bool valid = hFind != INVALID_HANDLE_VALUE; + FindClose(hFind); + return valid; + #else + struct stat s; + if (stat(path.c_str(), &s) == 0) { + if (s.st_mode & S_IFDIR) { + return true; + } else if (s.st_mode & S_IFREG) { + return true; + } else { + logger << Logger::ERR_MSG << "Invalid file: " << path << "\n"; + return false; + } + } + return false; + #endif + } + + /////////////////////////////////////////////////////////////////////////////////// + + void split( const std::string & path, std::string & head, std::string & tail ) { + size_t n = path.find_last_of('/'); + if ( n == std::string::npos ) { + n = path.find_last_of( '\\' ); + if ( n == std::string::npos ) { + head = ""; + tail = path; + return; + } + } + head = path.substr( 0, n ); + tail = path.substr( n+1 ); + } + + /////////////////////////////////////////////////////////////////////////////////// + } // namespace os::path + } // namespace os +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/Runtime/os.h b/src/Menge/MengeCore/Runtime/os.h new file mode 100644 index 00000000..55e55e08 --- /dev/null +++ b/src/Menge/MengeCore/Runtime/os.h @@ -0,0 +1,229 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file os.h + * @brief Various operating-system-dependent file-system operations. + * + * NOTE: The interface is modeled on python's os module. + */ + +#ifndef __OS_H__ +#define __OS_H__ + +#include +#include +#include +#include "CoreConfig.h" + +#ifdef _WIN32 +#include "windows.h" +/*! + * @brief The type for reporting file sizes. + */ +typedef DWORD FILE_SIZE; +#else +/*! + * @brief The type for reporting file sizes. + */ +typedef unsigned int FILE_SIZE; +#endif // _WIN32 + +/*! + * @brief A list of strings. + */ +typedef std::list< std::string > StringList; + +/*! + * @brief An interator into a list of strings. + */ +typedef StringList::iterator StringListItr; + +/*! + * @brief An const interator into a list of strings. + */ +typedef StringList::const_iterator StringListCItr; + +namespace Menge { + + /*! + * @namespace os + * @brief A compilation of file system operations. + * + * These are based loosely on the pythong os module and the interface + * is similar. + */ + namespace os { + /*! + * @brief Creates a list of all of the files in the given directory. + * + * @param path The path to a folder to search in. + * @param contents A vector of strings to populate with file names. + * @param wildcard The wild card to apply -- defaults to *. + * @returns True if the folder exists and was successfully read and the + * contents of the StringList are meaningful. False otherwise. + */ + MENGE_API bool listdir( const std::string & path, StringList & contents, const std::string & wildcard="*" ); + + /*! + * @brief Returns the file size (in bytes) of the file in the given path + * + * @param path The path to the file in question. + * @returns The size of the file or zero, if it is not a file or if there + * is an error in determining the size. + */ + MENGE_API FILE_SIZE fileSize( const std::string & path ); + + /*! + * @brief Formats the file size (in bytes) into an easily readable string. + * + * @param size The number of bytes. + * @returns A readable string. Limits the significant digits to just a few + * and scales the units (bytes, kb, Mb, Gb, etc.) appropriately. + */ + MENGE_API std::string fileSizeStr( FILE_SIZE size ); + + /*! + * @brief Removes the file located at the given path. + * + * @param path The path to the file to remove. + * @returns True if the file was successfully removed, false otherwise. + */ + MENGE_API bool remove( const std::string & path ); + + + /*! + * @brief Creates the indicated folder. + * + * This assumes that in the path given, all folders exist + * except the final folder. + * + * @param path The path of the folder to create. + * @returns True if the folder was successfully created, + * false otherwise. + */ + MENGE_API bool mkdir( const std::string & path ); + + /*! + * @brief Creates the folder given, and all missing + * folders in the path to that folder. + * + * @param path The path of the folder to create. + * @returns True if the folder was successfully created, + * false otherwise. + */ + MENGE_API bool makedirs( const std::string & path ); + + + /*! + * @namespace os::path + * @brief Aggregation of path-oriented, file system operations. + */ + namespace path { + /*! + * @brief Returns the absolute path of the given file resource + * + * e.g. if '.' is given, c:\\program files\test might be returned. + * + * @param path The path to the target resource. + * @param fullPath A string which will contain the full path + * @returns True if the full path could be found and placed in + * fullPath, false otherwise. + */ + MENGE_API bool absPath( const std::string & path, std::string & fullPath ); + + /*! + * @brief Reports if the path is a directory + * + * Bad files are considered to NOT be directories. + * + * @param path The path to a file location + * @returns True if the path resource is a directory, false + * otherwise. + */ + MENGE_API bool isdir( const std::string & path ); + + /*! + * @brief Joins multiple strings into a single path + * + * @param pathCount The number of strings to join. + * @param ... The strings. They must be char * (and not strings). + * @returns A string containing the joined path. + */ + MENGE_API std::string join( unsigned int pathCount, ... ); + + /*! + * @brief Reports if a file object exists + * + * @param path The path to the object in question. + * @returns True if the object indicated by path exists. + */ + MENGE_API bool exists( const std::string & path ); + + /*! + * @brief Splits the path at the last separator and returns + * the two parts. + * + * This is useful for popping levels off of a path to work closer + * and closer to the root directory. + * + * @param path The path to split. + * @param head The "head" of the path. + * @param tail The "tail" of the path (the element beyond + * the last separator. + */ + MENGE_API void split( const std::string & path, std::string & head, std::string & tail ); + + /*! + * @brief The separator for paths based on OS + * + * @returns A character representing the path separater for the + * OS. + */ + inline char pathSep() { + #ifdef _WIN32 + return '\\'; + #else + return '/'; + #endif + } + } + } // namespace os +} //namespace Menge + +#endif // __OS_H__ diff --git a/src/Menge/MengeCore/SceneGraph/Context.cpp b/src/Menge/MengeCore/SceneGraph/Context.cpp new file mode 100644 index 00000000..0354ae8c --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Context.cpp @@ -0,0 +1,196 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Context.h" +#include "GLScene.h" +#include "graphCommon.h" +#include "Select.h" +#include "GL/glu.h" +#include + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Context + /////////////////////////////////////////////////////////////////////////// + + void Context::uiSetup( int vWidth, int vHeight ) { + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, vWidth, 0.0, vHeight, -1.0f, 1.0f ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib( GL_ENABLE_BIT ); + glDisable( GL_DEPTH_TEST ); + } + + /////////////////////////////////////////////////////////////////////////// + + void Context::uiShutdown() { + glPopAttrib(); + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::getOpenGLView() { + glGetDoublev( GL_MODELVIEW_MATRIX, &_modViewMat[0] ); + glGetDoublev( GL_PROJECTION_MATRIX, &_projMat[0] ); + glGetIntegerv( GL_VIEWPORT, &_viewMat[0] ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::writeText( const std::string & txt, const Vector2 & pos, bool currColor ) const { + writeText( txt, Vector3( pos.x(), 0.f, pos.y() ), currColor ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::writeText( const std::string & txt, const Vector3 & pos, bool currColor ) const { + TextWriter * writer = TextWriter::Instance(); + double winx, winy, winz; + gluProject( pos.x(), pos.y(), pos.z(), _modViewMat, _projMat, _viewMat, &winx, &winy, &winz ); + writer->printText( txt, (float)winx, (float)winy, 15, currColor ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::writeTextRadially( const std::string & txt, const Vector2 & pos, const Vector2 & dir, bool currColor ) const { + TextWriter * writer = TextWriter::Instance(); + double winx, winy, winz; + gluProject( pos.x(), 0.f, pos.y(), _modViewMat, _projMat, _viewMat, &winx, &winy, &winz ); + float x = (float)winx; + float y = (float)winy; + Vector2 delta = pos + dir; + gluProject( delta.x(), 0.f, delta.y(), _modViewMat, _projMat, _viewMat, &winx, &winy, &winz ); + float dx = (float)winx - x; + float dy = (float)winy - y; + + float mag = sqrtf( dx * dx + dy * dy ); + float xWeight = 0.f; + float yWeight = 0.f; + if ( mag > 0.0001f) { + dx /= mag; + dy /= mag; + const float SQRT_2 = 0.707106781f; // sqrt(2)/2 + if ( fabs( dx ) >= SQRT_2 ) { + if ( dx < 0.f ) { + xWeight = 1.f; + } + yWeight = ( SQRT_2 - dy ) / ( 2.f * SQRT_2 ); + } else { // y is the dominant direction + if ( dy < 0.f ) { + yWeight = 1.f; + } + xWeight = ( SQRT_2 - dx ) / ( 2.f * SQRT_2 ); + } + } + writer->printAnchorText( txt, x, y, xWeight, yWeight, 15, currColor ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::writeAlignedText( const std::string & txt, const Vector2 & pos, TextWriter::Alignment align, bool currColor ) const { + TextWriter * writer = TextWriter::Instance(); + double winx, winy, winz; + gluProject( pos.x(), 0.f, pos.y(), _modViewMat, _projMat, _viewMat, &winx, &winy, &winz ); + writer->printText( txt, align, (float)winx, (float)winy, 15, currColor ); + } + + //////////////////////////////////////////////////////////////////////////// + + void Context::writeToScreen( const std::string & txt, TextWriter::Alignment align, int fontSize, float hPad, float vPad, bool currColor, bool trans ) const { + // draw text + TextWriter * writer = TextWriter::Instance(); + writer->printAlignText( txt, align, fontSize, hPad, vPad, currColor, trans ); + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR SelectContext + /////////////////////////////////////////////////////////////////////////// + + bool SelectContext::selectGL( const GLScene * scene, const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ) { + // perform selection + glPushAttrib( GL_ENABLE_BIT ); + glDisable( GL_LIGHTING ); + glDisable( GL_TEXTURE_2D ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + + camera.setSelectMat( selectPoint ); + camera.setGLView(); + + bool selChanged = false; + + Selectable::selectStart(); + drawUIGL( vWidth, vHeight, true ); + selChanged = Selectable::selectEnd(); + + // Nothing selected on the UI + if ( Selectable::getSelectedName() == 0 ) { + // Treat all 3D objects (UI and scene) the same + Selectable::selectStart(); + draw3DGL( true ); + GLNodeListCItr itr = scene->_nodes.begin(); + for ( ; itr != scene->_nodes.end(); ++itr ) { + (*itr)->drawGL( true ); + } + selChanged = Selectable::selectEnd(); + } + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); + + glPopAttrib(); + return selChanged; + } + } // namespace SceneGraph +} // namespace Menge diff --git a/src/Menge/MengeCore/SceneGraph/Context.h b/src/Menge/MengeCore/SceneGraph/Context.h new file mode 100644 index 00000000..02c31ad0 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Context.h @@ -0,0 +1,371 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Context.h + * @brief Defines a context for handling user interaction (mouse and keyboard input). + */ + +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ + +#include "CoreConfig.h" +//#include "SDL/SDL.h" +#include "GLCamera.h" +#include "TextWriter.h" + +// forward declaration +union SDL_Event; + +/*! + * @brief Forward declaration of the SDL event type. + */ +typedef SDL_Event SDL_Event; + +namespace Menge { + + /*! + * @namespace SceneGraph + * @brief The SceneGraph (SceneGraph) name space, containing all elements to use in a SceneGraph. + */ + namespace SceneGraph { + class Context; + class GLScene; + + // TODO: decouple this from SDL events + /*! + * @brief Defines the result of the context's consideration of user input. + */ + class MENGE_API ContextResult { + public: + /*! + * @brief Constructor + * + * @param handled Set to true if the event has been handled and does + * not need to be considered by any other handler. + * @param needsRedraw Set to true if the processing of the event requires a redraw. + */ + ContextResult( bool handled, bool needsRedraw ): _handled(handled), _redraw(needsRedraw){} + + /*! + * @brief Simple assignment operator overloaded. + * + * @param res Const reference to the ContextResult instance to copy from. + * @returns A reference to this context result. + */ + ContextResult & operator=( const ContextResult & res ) { _handled=res._handled; _redraw=res._redraw; return *this; } + + /*! + * @brief Sets the "handled" state to the given boolean state. + * + * @param state True means the result should consider the event handled, otherwise false. + */ + inline void setHandled( bool state ) { _handled = state; } + + /*! + * @brief Reports if the result considers the event handled. + * + * @returns True if the result considers the event handled, false otherwise. + */ + inline bool isHandled() const { return _handled; } + + /*! + * @brief Sets the "needs redraw" state to the given boolean state. + * + * @param state True means the result should believe the event requires a redraw, otherwise false. + */ + inline void setNeedsRedraw( bool state ) { _redraw = state; } + + /*! + * @brief Reports if the result believes the event handling requires a redraw. + * + * @returns True if the result requires a redraw, false otherwise. + */ + inline bool needsRedraw() const { return _redraw; } + + /*! + * @brief Sets the handled and needs redraw state simultaneously. + * + * @param handled True if the result should consider the event handled, false otherwise. + * @param redraw True means the result should believe the event requires a redraw, otherwise false. + */ + inline void set( bool handled, bool redraw ) { _handled = handled; _redraw = redraw; } + + /*! + * @brief Combines the provided context result with this one; flags are combined with a boolean OR. + * + * @param res The context results to combine with this. + */ + inline void combine( const ContextResult & res ) { _handled = _handled || res._handled; _redraw = _redraw || res._redraw; } + + friend class Context; + protected: + /*! + * @brief Reports if the event has been handled (and no one else needs to worry about it). + */ + bool _handled; + + /*! + * @brief Reports if the event requires a redraw on the scene. + */ + bool _redraw; + }; + + /*! + * @brief The base context class for defining a how events are handled. + * It also is responsible drawing UI elements in both screen space + * and in viewer world space. While the main viewer handles + * basic view manipulation, all other interactions should be handled + * with a context. + */ + class MENGE_API Context { + public: + /*! + * @brief Constructor. + */ + Context(){} + + /*! + * @brief Virtual destructor. + */ + virtual ~Context(){} + + /*! + * @brief The draw function for the context. + * + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + */ + virtual void drawGL( int vWidth, int vHeight ){} + + /*! + * @brief Performs selection based on a click on screen space. + * Uses the OpenGL selection mechanism. + * + * @param scene The scene to select in. + * @param camera The camera. + * @param vWidth The width of the viewport. + * @param vHeight The height of the viewport. + * @param selectPoint The point (in screen space) at which object selection + * should take place. + * @returns A boolean indicating whether a redraw needs to take place. + */ + virtual bool selectGL( const GLScene * scene, const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ) { return false; } + + /*! + * @brief Give the context the opportunity to respond to a mouse + * event. + * + * @param e The SDL event with the mouse event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual ContextResult handleMouse( SDL_Event & e ) { return ContextResult( false, false ); } + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual ContextResult handleKeyboard( SDL_Event & e ) { return ContextResult( false, false ); } + + /*! + * @brief Allow the context to update any time-dependent state it might have to + * the given global time. + */ + virtual void update() {} + + /*! + * @brief Callback for when the OpenGL context is changed. + */ + virtual void newGLContext() {} + + /*! + * @brief Called when the context is activated. + */ + virtual void activate() {} + + /*! + * @brief Called when the context is deactivated. + */ + virtual void deactivate() {} + + protected: + /*! + * @brief UI setup - handles the configuration of the opengl context + * for orthographic rendering. + * + * @param vWidth The width of the view (in pixels). + * @param vHeight The height of the view (in pixels). + */ + void uiSetup( int vWidth, int vHeight ); + + /*! + * @brief Cleans up the OpenGL state after having drawn the UI elements of + * the context. + */ + void uiShutdown(); + + /*! + * @brief Draw UI elements into the context. + * + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void drawUIGL( int vWidth, int vHeight, bool select=false ) {}; + + /*! + * @brief Draw context elements into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( bool select=false ) {}; + + /*! + * @brief Updates the various view matrices: modelview, + * projection, and view. + */ + void getOpenGLView(); + + /*! + * @brief Writes the given text at the given location + * @param txt The text to write to the screen. + * @param pos The position, in world coordinates, to place the text + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + */ + void writeText( const std::string & txt, const Vector2 & pos, bool currColor=false ) const; + + /*! + * @brief Writes the given text at the given 3D location + * @param txt The text to write to the screen. + * @param pos The position, in world coordinates, to place the text + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + */ + void writeText( const std::string & txt, const Vector3 & pos, bool currColor=false ) const; + + /*! + * @brief Writes the given text at the given location, but anchored + * based on the radial direction given. + * @param txt The text to write to the screen. + * @param pos The position, in world coordinates, to place the text + * @param dir A vector representing the direction of the radius at whose + * end the text should be placed. Direction defined in + * world coordinates + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + */ + void writeTextRadially( const std::string & txt, const Vector2 & pos, const Vector2 & dir, bool currColor=false ) const; + + /*! + * @brief Writes the given text aligned to the given location + * @param txt The text to write to the screen. + * @param pos The position, in world coordinates, to place the text + * @param align TextWriter alignment specification. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + */ + void writeAlignedText( const std::string & txt, const Vector2 & pos, TextWriter::Alignment align, bool currColor=false ) const; + + /*! + * @brief Writes the given text to the screen based on the given alignment. + * + * The text will be written to one of 9 locations: + * - Top left corner, top center, top right corner + * - left center, screen center, right center + * - bottom left corner, bottom center, bottom right corner + * + * @param txt The text to write to the screen. + * @param align TextWriter alignment specification. + * @param fontSize The size of the text to write. + * @param hPad The number of pixels to pad the text horizontally. + * @param vPad The number of pixels to pad the text vertically. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + * @param trans Determines if the text is printed transparently (true) + * or not (false). + */ + void writeToScreen( const std::string & txt, TextWriter::Alignment align, int fontSize, float hPad=0.f, float vPad=0.f, bool currColor=false, bool trans=true ) const; + + /*! + * @brief The current model view matrix + */ + double _modViewMat[16]; + + /*! + * @brief The current projection matrix + */ + double _projMat[16]; + + /*! + * @brief The current viewport parameters + */ + int _viewMat[4]; + }; + + /*! + * @brief A context that performs object selection by directly clicking on selectable entities + * in the OpenGL context. + */ + class MENGE_API SelectContext : public Context { + public: + /*! + * @brief Performs selection based on a click on screen space. + * Uses the OpenGL selection mechanism. + * + * @param scene The scene to select in. + * @param camera The camera. + * @param vWidth The width of the viewport. + * @param vHeight The height of the viewport. + * @param selectPoint The point (in screen space) at which object selection + * should take place. + * @returns A boolean indicating whether a redraw needs to take place. + */ + virtual bool selectGL( const GLScene * scene, const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ); + }; + + } // namespace SceneGraph +} // namespace Menge +#endif // __CONTEXT_H__ diff --git a/src/Menge/MengeCore/SceneGraph/ContextSwitcher.cpp b/src/Menge/MengeCore/SceneGraph/ContextSwitcher.cpp new file mode 100644 index 00000000..7e68b1ed --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/ContextSwitcher.cpp @@ -0,0 +1,177 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ContextSwitcher.h" + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR ContextSwitcher + /////////////////////////////////////////////////////////////////////////// + + ContextSwitcher::ContextSwitcher(): Context(), _activeContext(0x0) { + } + + /////////////////////////////////////////////////////////////////////////// + + ContextSwitcher::~ContextSwitcher() { + if ( _activeContext ) { + _activeContext->deactivate(); + } + KeyContextMap::iterator itr = _contexts.begin(); + for ( ; itr != _contexts.end(); ++itr ) { + delete itr->second; + } + } + + /////////////////////////////////////////////////////////////////////////// + + void ContextSwitcher::addContext( Context * context, SDLKey key ) { + KeyContextMap::iterator itr = _contexts.find( key ); + if ( itr != _contexts.end() ) { + delete itr->second; + } + _contexts[ key ] = context; + } + + /////////////////////////////////////////////////////////////////////////// + + void ContextSwitcher::newGLContext() { + KeyContextMap::iterator itr = _contexts.begin(); + for ( ; itr != _contexts.end(); ++itr ) { + itr->second->newGLContext(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + bool ContextSwitcher::switchContexts( Context * context ) { + if ( _activeContext != context ) { + if ( _activeContext ) { + _activeContext->deactivate(); + } + _activeContext = context; + if ( _activeContext ) { + _activeContext->activate(); + } + return true; + } + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + void ContextSwitcher::update() { + if ( _activeContext ) { + _activeContext->update(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + ContextResult ContextSwitcher::handleKeyboard( SDL_Event & e ) { + // The work flow is like this: + // Escape is the only key that the switcher will definitely interpret + // If the escape key is selected, the active context is cleared + // If the key is not escape: + // If there is an active context, it gets the chance to handle it + // If the active context doesn't handle it, then the switcher tries + // switching + // otherwise, it returns back to the caller + ContextResult result( false, false ); + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + if ( e.type == SDL_KEYDOWN ) { + if ( e.key.keysym.sym == SDLK_ESCAPE && noMods) { + bool changed = switchContexts( 0x0 ); + result.set( true, changed ); + } + + if ( ! result.isHandled() ) { + if ( _activeContext ) { + result = _activeContext->handleKeyboard( e ); + } else { + KeyContextMap::iterator itr = _contexts.find( e.key.keysym.sym ); + if ( itr != _contexts.end() ) { + Context * ctx = itr->second; + bool changed = switchContexts( ctx ); + + return ContextResult( true, changed ); + } + } + } + } + return result; + } + + /////////////////////////////////////////////////////////////////////////// + + ContextResult ContextSwitcher::handleMouse( SDL_Event & e ) { + if ( _activeContext ) { + return _activeContext->handleMouse( e ); + } else { + return ContextResult( false, false ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void ContextSwitcher::drawGL( int vWidth, int vHeight ) { + if ( _activeContext ) { + _activeContext->drawGL( vWidth, vHeight ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + bool ContextSwitcher::selectGL( const GLScene * scene, const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ) { + if ( _activeContext ) { + return _activeContext->selectGL( scene, camera, vWidth, vHeight, selectPoint ); + } + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/ContextSwitcher.h b/src/Menge/MengeCore/SceneGraph/ContextSwitcher.h new file mode 100644 index 00000000..4837fd52 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/ContextSwitcher.h @@ -0,0 +1,159 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ContextSwitcher.h + * @brief The definition of a context which allows the ability to select between + * multiple contexts. + */ + +#ifndef __CONTEXT_SWITCHER_H__ +#define __CONTEXT_SWITCHER_H__ + +#include "Context.h" +#include + +namespace Menge { + namespace SceneGraph { + /*! + * @brief A mapping from a SDL key value and a context + */ + typedef std::map< SDLKey, Context * > KeyContextMap; + + /*! + * @brief Special context for switching between multiple contexts. + * Each context tied to a keyboard shortcut. + */ + class MENGE_API ContextSwitcher : public Context { + public: + /*! + * @brief Constructor. + */ + ContextSwitcher(); + + /*! + * @brief Destructor. + */ + virtual ~ContextSwitcher(); + + /*! + * @brief Add a context and it's "hotkey" + * + * @param context The context to add. + * @param key The key which activates the context. + */ + void addContext( Context * context, SDLKey key ); + + /*! + * @brief Switch to the indicated context. + * + * @param context The newly active context. + * @returns A boolean reporting if a change is actually made (true) + * or not (false). + */ + bool switchContexts( Context * context ); + + /*! + * @brief Allow the context to update its time-dependent state to + * the given global time. + */ + virtual void update(); + + /*! + * @brief The draw function for the context. + * + * @param vWidth The width of the viewport (in pixels). + * @param vHeight The height of the viewport (in pixels). + */ + virtual void drawGL( int vWidth, int vHeight ); + + /*! + * @brief Performs selection based on a click on screen space. + * Uses the OpenGL selection mechanism. + * + * @param scene The scene to select in. + * @param camera The camera. + * @param vWidth The width of the viewport. + * @param vHeight The height of the viewport. + * @param selectPoint The point (in screen space) at which object selection + * should take place. + * @returns A boolean indicating whether a redraw needs to take place. + */ + virtual bool selectGL( const GLScene * scene, const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ); + + /*! + * @brief Callback for when the OpenGL context is changed. + */ + virtual void newGLContext(); + + /*! + * @brief Give the context the opportunity to respond to a mouse + * event. + * + * @param e The SDL event with the mouse event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual ContextResult handleMouse( SDL_Event & e ); + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual ContextResult handleKeyboard( SDL_Event & e ); + + protected: + + /*! + * @brief The currently active context + */ + Context * _activeContext; + + /*! + * @brief A mapping for key to context. + */ + KeyContextMap _contexts; + }; + } // namespace SceneGraph +} // namespace Menge + +#endif // __CONTEXT_SWITCHER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLCamera.cpp b/src/Menge/MengeCore/SceneGraph/GLCamera.cpp new file mode 100644 index 00000000..1b331577 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLCamera.cpp @@ -0,0 +1,406 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "graphCommon.h" +#include "GLCamera.h" +#include +#include + +#include + +namespace Menge { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + const Vector3 DEFAULT_POS = Vector3( 0.f, 1.f, -5.f ); + const Vector3 DEFAULT_TARGET = Vector3(); + const Vector3 DEFAULT_UP = Vector3(0.0, 1.0, 0.0 ); + +#endif // DOXYGEN_SHOULD_SKIP_THIS + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // Implementation for GLCamera + /////////////////////////////////////////////////////////////////////////// + + GLCamera::GLCamera(): _type(PERSP), _position(DEFAULT_POS), _target( DEFAULT_TARGET ), _up(DEFAULT_UP), + _farPlane( 100.f ), _nearPlane(0.01f), _fov(45.f), _viewWidth(640), _viewHeight(480), _dirtyProj(false), _orthoHWidth(1.f) {} + + /////////////////////////////////////////////////////////////////////////// + + GLCamera::GLCamera( const Vector3 & p): _type(PERSP), _position(p), _target( DEFAULT_TARGET ), _up(DEFAULT_UP), + _farPlane( 100.f ), _nearPlane(0.01f), _fov(45.f), _viewWidth(640), _viewHeight(480), _dirtyProj(false), _orthoHWidth(1.f) {} + + /////////////////////////////////////////////////////////////////////////// + + GLCamera::GLCamera( const Vector3 & p, const Vector3 & t): _type(PERSP), _position(p), _target( t ), _up(DEFAULT_UP), + _farPlane( 100.f ), _nearPlane(0.01f), _fov(45.f), _viewWidth(640), _viewHeight(480), _dirtyProj(false), _orthoHWidth(1.f) {} + + /////////////////////////////////////////////////////////////////////////// + + GLCamera::GLCamera( const Vector3 & p, const Vector3 & t, const Vector3 & u): _type(PERSP), _position(p), _target( t ), _up(u), + _farPlane( 100.f ), _nearPlane(0.01f), _fov(45.f), _viewWidth(640), _viewHeight(480), _dirtyProj(false), _orthoHWidth(1.f) {} + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setOrtho( float scaleFactor ) { + _type = ORTHO; + // Compute the ortho width + _orthoHWidth = 0.5f * _position.distance( _target ) / scaleFactor ; + _dirtyProj = true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setPersp() { + _type = PERSP; + _position = ( -2.f * _orthoHWidth ) * targetDir() + _target; + _dirtyProj = true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setActive() { + _dirtyProj = true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setPosition( const Vector3 & p ) { + _position = p; + _orthoHWidth = _position.distance( _target ) * 0.5f; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setPosition( float x, float y, float z ) { + _position.set( x, y, z ); + _orthoHWidth = _position.distance( _target ) * 0.5f; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setTarget( const Vector3 & t ) { + _target = t; + _orthoHWidth = _position.distance( _target ) * 0.5f; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setTarget( float x, float y, float z ) { + _target.set( x, y, z ); + _orthoHWidth = _position.distance( _target ) * 0.5f; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setUp( const Vector3 & u ) { + _up = u; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setUp( float x, float y, float z ) { + _up.set( x, y, z ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setViewport( int w, int h, int left, int bottom ) { + _viewWidth = w; + _viewHeight = h; + glViewport( left, bottom, w, h ); + _dirtyProj = true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setProjMat( int w, int h ) const { + _viewWidth = w; + _viewHeight = h; + glViewport( 0, 0, w, h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + _setProjMat(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setSelectMat( int * selectPoint ) const { + const int PICK_SIZE = 5; + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + int viewport[4] = { 0, 0, _viewWidth, _viewHeight }; + gluPickMatrix( selectPoint[0], _viewHeight - selectPoint[1], PICK_SIZE, PICK_SIZE, viewport ); + _setProjMat(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::_setProjMat() const { + if ( _type == PERSP ) { + gluPerspective( _fov, (float)_viewWidth/(float)_viewHeight, _nearPlane, _farPlane ); + } else { + float halfHeight = _orthoHWidth * (float)_viewHeight / (float)_viewWidth; + glOrtho( -_orthoHWidth, _orthoHWidth, + -halfHeight, halfHeight, + _nearPlane, _farPlane ); + } + glMatrixMode( GL_MODELVIEW ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::setGLView() const { + // TODO: Make this vary according to perspective vs. ortho + if ( _dirtyProj ) { + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + _setProjMat(); + _dirtyProj = false; + } + glLoadIdentity(); + gluLookAt( _position[0], _position[1], _position[2], + _target[0], _target[1], _target[2], + _up[0], _up[1], _up[2] ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::viewXAxis( bool downPositive ) { + float camDist = _position.distance( _target ); + if ( downPositive ) { + _position.set( _target.x() - camDist, _target.y(), _target.z() ); + } else { + _position.set( _target.x() + camDist, _target.y(), _target.z() ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::viewYAxis( bool downPositive ) { + float camDist = _position.distance( _target ); + if ( downPositive ) { + _position.set( _target.x(), _target.y() - camDist, _target.z() + 0.01f ); + } else { + _position.set( _target.x(), _target.y() + camDist, _target.z() + 0.01f ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::viewZAxis( bool downPositive ) { + float camDist = _position.distance( _target ); + if ( downPositive ) { + _position.set( _target.x(), _target.y(), _target.z() - camDist ); + } else { + _position.set( _target.x(), _target.y(), _target.z() + camDist ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::pan( float angle ) { + Vector3 targetDisp = _target - _position; + targetDisp = targetDisp.rotateY( angle ); + _target = _position + targetDisp; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::tilt( float angle ) { + Vector3 targetDisp = _target - _position; + targetDisp = targetDisp.rotateV( angle, getRightDir() ); + _target = _position + targetDisp; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::truck( float amount ) { + float scale; + if ( _type == PERSP ) { + scale = targetDistance(); + } else { + scale = 2.f * _orthoHWidth; + } + Vector3 offset = getRightDir() * ( amount * scale ); + _target += offset; + _position += offset; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::crane( float amount ) { + float scale; + if ( _type == PERSP ) { + scale = targetDistance(); + } else { + scale = 2.f * _orthoHWidth; + } + Vector3 offset = getActualUpDir() * ( amount * scale ); + _target += offset; + _position += offset; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::dolly ( float amount ) { + Vector3 offset = targetDir() * amount; + _target += offset; + _position += offset; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::dollyPlane( float amount ) { + Vector3 offset = targetDir() * amount; + offset[1] = 0.0; + _target += offset; + _position += offset; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::zoom( float amount ) { + if ( _type == PERSP ) { + float tgtDist = targetDistance(); + float scaledAmount = amount * tgtDist / 100.f; + if ( (tgtDist - scaledAmount <= 0.1f ) ) + scaledAmount = tgtDist - 0.1f; + Vector3 offset = targetDir() * scaledAmount; + _position += offset; + } else { + float scaledAmount = amount * _orthoHWidth / 100.f; + if ( _orthoHWidth - scaledAmount <= 0.1f ) { + scaledAmount = _orthoHWidth - 0.1f; + } + _orthoHWidth -= scaledAmount; + _dirtyProj = true; + } + } + + /////////////////////////////////////////////////////////////////////////// + + + void GLCamera::orbitVerticalAxis( float angle ) { + Vector3 cameraDir = _position - _target; + cameraDir = cameraDir.rotateY( angle ); + _position = _target + cameraDir; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::orbitHorizontalAxis( float angle ) { + Vector3 cameraDisp = _position - _target; + Vector3 cameraDir = cameraDisp; + cameraDir.normalize(); + float oldAngle = acos( cameraDir * Vector3( 0.0f, 1.0f, 0.0f ) ); + if ( oldAngle - angle >= PI ) { + angle = oldAngle - PI + 0.01f; + } else if ( oldAngle - angle <= 0.0f ) { + angle = oldAngle - 0.01f; + } + cameraDisp = cameraDisp.rotateV( angle, getRightDir() ); + _position = _target + cameraDisp; + } + + /////////////////////////////////////////////////////////////////////////// + + float GLCamera::targetDistance() const { + return _target.distance( _position ); + } + + /////////////////////////////////////////////////////////////////////////// + + Vector3 GLCamera::targetDir() const { + Vector3 temp = _target - _position; + temp.normalize(); + return temp; + } + + /////////////////////////////////////////////////////////////////////////// + + Vector3 GLCamera::getActualUpDir() const{ + Vector3 front = _target - _position; + Vector3 right = front.cross( _up ); + right = right.cross( front ); + right.normalize(); + return right; + } + + /////////////////////////////////////////////////////////////////////////// + + Vector3 GLCamera::getRightDir() const{ + Vector3 targetDir = _target - _position; + targetDir = targetDir.cross( _up); + targetDir.normalize(); + return targetDir; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLCamera::outputState() const { + std::cout << "\n"; + } + + /////////////////////////////////////////////////////////////////////////// + + float GLCamera::getOrthoScaleFactor() const { + float dist = targetDistance(); + return 0.5f * dist / _orthoHWidth; + } + + } // namespace SceneGraph + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLCamera.h b/src/Menge/MengeCore/SceneGraph/GLCamera.h new file mode 100644 index 00000000..4af7c099 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLCamera.h @@ -0,0 +1,522 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLCamera.h + * @brief Class to handle camera transformations in OpenGL + */ +#ifndef __GLCAMERA_H__ +#define __GLCAMERA_H__ + +#include "CoreConfig.h" +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + /*! + * @brief The class for controlling the view camera: it's position, orientation + * field of view, projection matrix, etc. + */ + class MENGE_API GLCamera { + public: + /*! + * @brief Determines the projection matrix of the 3D camera + */ + enum CamEnum { ORTHO, + PERSP }; + + /*! + * @brief Default constructor. + */ + GLCamera(); + + /*! + * @brief Constructor for setting camera position. + * + * @param p The position of the camera. + */ + GLCamera( const Vector3 & p); + + /*! + * @brief Constructor for setting camera position and target. + * + * @param p The position of the camera. + * @param t The position of the camera's view target. + */ + GLCamera( const Vector3 & p, const Vector3 & t); + + /*! + * @brief Constructor for setting camera position, target, + * and up vector. + * + * @param p The position of the camera. + * @param t The position of the camera's view target. + * @param u the direction of the camera's up direction. + */ + GLCamera( const Vector3 & p, const Vector3 & t, const Vector3 & u); + + /*! + * @brief Sets the camera to use an orthographic projection. + * + * @param scaleFactor Defines the horizontal span of the orthographic + * view as a function of the distance to target. + * This "zooms" the orthographic camera closer. + */ + void setOrtho( float scaleFactor=1.f ); + + /*! + * @brief Sets the camera to use a perspective projection. + */ + void setPersp(); + + /*! + * @brief Called the first time a camera is put into use. + * Failing to call this may lead to unexpected camera settings until + * the camera is manipulated. + */ + void setActive(); + + /*! + * @brief Return the position of the camera. + * + * @returns The position fo the camera in 3D space. + */ + Vector3 getPosition() const { return _position; } + + /*! + * @brief Set the camera position explicitly from a Vector3. + * + * @param p The desired position of the camera. + */ + void setPosition( const Vector3 & p ); + + /*! + * @brief Set the camera position explicitly from three values. + * + * @param x The position of the camera along the x-axis. + * @param y The position of the camera along the y-axis. + * @param z The position of the camera along the z-axis. + */ + void setPosition( float x, float y, float z ); + + /*! + * @brief Return the position of the camera's view target. + * + * @returns The position of the camera's view target. + */ + Vector3 getTarget() const { return _target; } + + /*! + * @brief Set the position of the camera's view target explicitly from a Vector3. + * + * @param p The desired position of the camera's view target. + */ + void setTarget( const Vector3 & p ); + + /*! + * @brief Set the position of the camera's view target explicitly from three values. + * + * @param x The position of the camera's view target along the x-axis. + * @param y The position of the camera's view target along the y-axis. + * @param z The position of the camera's view target along the z-axis. + */ + void setTarget( float x, float y, float z ); + + /*! + * @brief Return the orientation of the camera's up direction. + * + * @returns The orientation of the camera's up direction. + */ + Vector3 getUp() const { return _up; } + + /*! + * @brief Set the orientation of the camera's up vector from a Vector3. + * + * @param u The desired direction of the camera's up direction. + * It is assumed to be of normal length. + */ + void setUp( const Vector3 & u ); + + /*! + * @brief Set the orientation of the camera's up vector from three values. + * + * @param x The x-component of the camera's up vector. + * @param y The y-component of the camera's up vector. + * @param z The z-component of the camera's up vector. + */ + void setUp( float x, float y, float z ); + + /*! + * @brief Sets the field of view of the camera -- only applicable + * when using the perspective projection. + * + * @param fov The horizontal field of view (in degrees). + */ + inline void setFOV( float fov ) { _fov = fov; } + + /*! + * @brief Returns the current horizontal field of view (in degrees). + */ + inline float getFOV() const { return _fov; } + + /*! + * @brief Sets the far plane distance. + * + * @param fp The desired far plane distance. + */ + inline void setFarPlane( float fp ) { _farPlane = fp; } + + /*! + * @brief Reports the camera's current far plane distance. + * + * @returns The camera's current far plane distance. + */ + inline float getFarPlane() const { return _farPlane; } + + /*! + * @brief Sets the near plane distance. + * + * @param np The desired near plane distance. + */ + inline void setNearPlane( float np ) { _nearPlane = np; } + + /*! + * @brief Reports the camera's current near plane distance. + * + * @returns The camera's current near plane distance. + */ + inline float getNearPlane() const { return _nearPlane; } + + /*! + * @brief Reports the orthographic scale factor for this camera. + * + * The orthographic scale factor is the value which determines + * how "zoomed in" an orthographic camera is. It is the ratio + * of the distance between camera and target and the + * width of the viewable region in orthographic. + * + * @returns The orthographic scale + */ + float getOrthoScaleFactor() const; + + /*! + * @brief Sets the camera's viewport to a view with the given + * width and height dimensions. + * + * @param w The width of the viewport (in pixels) + * @param h The height of the viewport (in pixels ) + * @param left The position of the left-most edge of the viewport + * in pixels. Defaults to zero. + * @param bottom The position of the bottom-most edge of the viewport + * in pixels. Defaults to zero. + */ + void setViewport( int w, int h, int left=0, int bottom=0 ); + + /// Create OpenGL commands + + /*! + * @brief Emits the appropriate OpenGL commands for setting up a projection + * matrix. + * + * @param w The viewport width (in pixels). + * @param h The viewport height (in pixels). + */ + void setProjMat( int w, int h ) const ; + + /*! + * @brief Emits the appropriate OpenGL commands for setting up a selection context. + * + * @param selectPoint A pointer to an array of two floats interpreted as the + * x- and y-positions of the selection point, in screen space. + */ + void setSelectMat( int * selectPoint ) const ; + + /*! + * @brief Emits the appropriate OpenGL commands for setting up the view for this camera. + */ + void setGLView() const; + + /*! + * @brief Sets the camera to look along the world's x-axis. + * + * The camera's distance from the origin is the same as its previous + * displacement from the origin along the x-axis. + * + * @param downPositive If true, the camera looks along the positive x-axis + * direction. If false, it looks in the negative direction. + */ + void viewXAxis( bool downPositive=true ); + + /*! + * @brief Sets the camera to look along the world's y-axis. + * + * The camera's distance from the origin is the same as its previous + * displacement from the origin along the y-axis. + * + * @param downPositive If true, the camera looks along the positive y-axis + * direction. If false, it looks in the negative direction. + */ + void viewYAxis( bool downPositive=true ); + + /*! + * @brief Sets the camera to look along the world's z-axis. + * + * The camera's distance from the origin is the same as its previous + * displacement from the origin along the z-axis. + * + * @param downPositive If true, the camera looks along the positive z-axis + * direction. If false, it looks in the negative direction. + */ + void viewZAxis( bool downPositive=true ); + + /*! + * @brief Causes the camera to "pan" the given angle. + * + * The camera "pans" by rotating around its own center along + * the world's vertical axis (i.e., turning left and right). + * + * @param angle The amount of pan (in radians). Positive + * values cause the camera to turn left, negative values + * turn the camera right. + */ + void pan( float angle ); + + /*! + * @brief Causes the camera to "tilt" the given angle. + * + * The camera "tilts" by rotating around its own center along + * the its own horizontal axis (i.e., looking up and down). + * + * @param angle The amount of pan (in radians). Postive + * values rotates the camera down, negative rotates up. + */ + void tilt( float angle ); + + /*! + * @brief Causes the camera to "truck" the given amount. + * + * "Trucking" is moving the camera side to side on its own horizontal + * axis (i.e., "strafe" left and right). + * + * @param amount The amount to move. Postive values move the camera to its + * right and negative values move left. + */ + void truck( float amount ); + + /*! + * @brief Causes the camera to "crane" the given amount. + * + * A camera "cranes" by moving along its own vertical axis. + * This causes the camera to rise and lower in its view. + * The actual movement in the WORLD coordinate system depends on + * the camera's orientation. + * + * @param amount The amount to move. Postive values move the camera up and + * negative values move down. + */ + void crane( float amount ); + + /*! + * @brief Causes the camera to "dolly" in and out. + * + * Dollying a camera moves it forward and backward in the camera's facing + * direction (i.e., moving in the direction of the target). The target + * moves with the camera. + * + * @param amount The amount to move. Positive values move forward and + * negative values move backward. + */ + void dolly ( float amount ); + + /*! + * @brief Causes the camera to "dolly" along a plane. + * + * In this case, the elevation (in world space) does not change. The + * camera moves parallel with the ground plane based on the projeciton + * of the camera's facing direction on that plane. + * + * @param amount The amount to move. Positive values move forward and + * negative values move backward. + */ + void dollyPlane( float amount ); + + /*! + * @brief Causes the camera to "zoom" toward its target. + * + * This is not a zoom in the sense that the lens focal length + * changes. This merely moves the camera along its facing direction + * while holding the target stationary. + * + * @param amount The amount to zoom. Positive values move forward and + * negative values move backward. + */ + void zoom( float amount ); + + /*! + * @brief Causes the camera to rotate an axis, parallel with the world vertical + * axis centered on the camera's target. + * + * @param angle The angle of rotation (in radians). Positive values move the camera + * to its right, negative to its left. + */ + void orbitVerticalAxis( float angle ); + + /*! + * @brief Camera rotates, at distance, around target on axis parallel to camera's horizontal axis. + * + * @param angle The angle of rotation (in radians). Positive values move the camera + * in its upward direction, negative to its downward. + */ + void orbitHorizontalAxis( float angle ); + + /// Camera state + + /*! + * @brief Returns distance between camera and target + * + * @returns The distance between camera and its target. + */ + float targetDistance() const; + + /*! + * @brief Returns the unit-length vector indicating direction FROM camera to TARGET. + * + * @returns Direction to target in world space. + */ + Vector3 targetDir() const; + + /*! + * @brief Returns the ACTUAL up dir -- as opposed to the desired up. + * + * Essentially, the cross product of the camera's horizontal direction + * with its facing direction. + * + * @returns Camera's current, local up vector in world space. + */ + Vector3 getActualUpDir() const; + + /*! + * @brief Returns the normalized vector representing the camera's horizontal axis pointing to right + * + * @returns The direction of the camera's right in world space. + */ + Vector3 getRightDir() const; + + /*! + * @brief Outputs the state of the camera to the console. + * + * The format can be cut-and-pasted into a view configuration file. + */ + void outputState() const; + + private: + + /*! + * @brief Determines the camera projeciton type: orthographic or perspective. + */ + CamEnum _type; + + /*! + * @brief Position of camera -- used for both perspective and orthographic. + */ + Vector3 _position; + + /*! + * @brief Position of the camera's target -- used primarily for perspective. + */ + Vector3 _target; + + /*! + * @brief The desired up direction for the camera. Only relevant for the + * perspective camera. + */ + Vector3 _up; + + /*! + * @brief The distance from the camera to the camera's far clipping plane + */ + float _farPlane; + + /*! + * @brief The distance from the camera to the camera's near clipping plane. + */ + float _nearPlane; + + /*! + * @brief The horizontal angle of field of view. + */ + float _fov; + + /*! + * @brief The viewport's width. (It is assumed that the viewport's origin is + * at (0,0). Mutable because it changes during screen resizes. + */ + mutable unsigned int _viewWidth; + + /*! + * @brief The viewport's height. (It is assumed that the viewport's origin is + * at (0,0). Mutable because it changes during screen resizes. + */ + mutable unsigned int _viewHeight; + + /*! + * @brief Deterimines if the projection matrix needs to be recomputed. + */ + mutable bool _dirtyProj; + + /*! + * @brief The width of the orthographic display. Combined with the scale factor + * determines the scope of the orthographic view. + * + * @see setOrtho + */ + float _orthoHWidth; + + /*! + * @brief Common camera projection functionality shared by both perspective and orthographic + * projections. + */ + void _setProjMat() const; + }; + + } // namespace SceneGraph +} // namespace Menge + +#endif diff --git a/src/Menge/MengeCore/SceneGraph/GLContextManager.cpp b/src/Menge/MengeCore/SceneGraph/GLContextManager.cpp new file mode 100644 index 00000000..5abba0e5 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLContextManager.cpp @@ -0,0 +1,64 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GLContextManager.h" + +namespace Menge { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR GLContextManager + /////////////////////////////////////////////////////////////////////////// + + std::list< void (*)() > GLContextManager::_rsrcCallbacks; + + /////////////////////////////////////////////////////////////////////////// + + void GLContextManager::addCallback( void (*func)() ) { + _rsrcCallbacks.push_back( func ); + } + /////////////////////////////////////////////////////////////////////////// + + void GLContextManager::newGLContext() { + std::list< void (*)() >::iterator itr = _rsrcCallbacks.begin(); + for ( ; itr != _rsrcCallbacks.end(); ++itr ) { + (*(*itr))(); // the iterator gets dereferenced and then the function pointer. + } + } + + /////////////////////////////////////////////////////////////////////////// +} // namespace Menge diff --git a/src/Menge/MengeCore/SceneGraph/GLContextManager.h b/src/Menge/MengeCore/SceneGraph/GLContextManager.h new file mode 100644 index 00000000..a3088192 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLContextManager.h @@ -0,0 +1,88 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLContextManager.h + * @brief The mechanism by which OpenGL memory structures are restored after + * an OpenGL context change.. + */ + +#ifndef __GL_CONTEXT_MANAGER_H__ +#define __GL_CONTEXT_MANAGER_H__ + +#include "CoreConfig.h" +#include + +namespace Menge { + + /*! + * @brief Handles updating the scene graph when there is a new OpenGL context. + * + * Through this class and its static members, all of the resources used in the scene graph + * are refreshed when the OpenGL context changes. + * + * Each resource registers a refresh callback to the manager and then the viewer, when + * changin GL Contexts, calls newGLContext() to have the resources update. + * + * If any new resources are added to the SceneGraph which have OpenGL-dependent memory + * (such as textures, display lists, arrays of data, etc.) that class must provide + * a static callback method and register it so its data can be restored in the new + * context (e.g. ImageData, Circle, Cylinder, etc.). + */ + class MENGE_API GLContextManager { + /*! + * @brief A list of callbacks for performing context changes. + */ + static std::list< void (*)() > _rsrcCallbacks; + + public: + /*! + * @brief Register a new class callback to the context manager. + * + * @param newGLContext A pointer to the callback function. + */ + static void addCallback( void (*newGLContext)() ); + + /*! + * @brief Called when the OpenGL context changes - triggers all of + * the registered callbacks. + */ + static void newGLContext(); + }; +} // namespace Menge +#endif // __GL_CONTEXT_MANAGER_H__ diff --git a/src/Menge/MengeCore/SceneGraph/GLGroundPlane.cpp b/src/Menge/MengeCore/SceneGraph/GLGroundPlane.cpp new file mode 100644 index 00000000..50837b17 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLGroundPlane.cpp @@ -0,0 +1,213 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "graphCommon.h" +#include "GLGroundPlane.h" +#include + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // Implementation of GLGroundPlane + /////////////////////////////////////////////////////////////////////////// + + GLGroundPlane::GLGroundPlane( float width, float height, float majorDist, int minorCount ): GLNode(), + _width( width ), _height( height ), _majorDist( majorDist ), _minorCount( minorCount ), GL_ID( 0 ), + _lineColor(0.f, 0.f, 0.f) { + } + + /////////////////////////////////////////////////////////////////////////// + + GLGroundPlane::~GLGroundPlane(void) { + if ( GL_ID ) clearGL(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::setWidth( float w ) { + if ( _width != w ) clearGL(); + _width = w; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::setHeight( float h ) { + if ( _height != h ) clearGL(); + _height = h; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::setMajorDistance( float dist ) { + if ( _majorDist != dist ) clearGL(); + _majorDist = dist; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::setMinorCount( int count ) { + if ( _minorCount != count ) clearGL(); + _minorCount = count; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::drawGL( bool select ) { + if ( !select ) { + glPushAttrib( GL_LINE_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT ); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable( GL_TEXTURE_2D ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask( false ); + glCallList( GL_ID ); + glDepthMask( true ); + glPopAttrib(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::plotGL() { + float halfWidth = (float)_width * 0.5f; + float halfHeight = (float)_height * 0.5f; + + const float DEPTH = 0.f; + float gridMaxW = floor( halfWidth / _majorDist ) * _majorDist; + float gridMaxH = floor( halfHeight / _majorDist ) * _majorDist; + + glPushAttrib( GL_CURRENT_BIT ); + // minor lines + glColor4f( _lineColor.x(), _lineColor.y(), _lineColor.z(), 0.05f ); + glLineWidth( 1.0f ); + float minorDist = _majorDist / ( _minorCount + 1 ); + // horizontal lines + float val = -gridMaxH; + glBegin( GL_LINES ); + int lineCount = 0; + while ( val <= gridMaxH ) { + if ( lineCount % ( _minorCount + 1 ) ) { + glVertex3f( -gridMaxW, DEPTH, val ); + glVertex3f( gridMaxW, DEPTH, val ); + } + lineCount += 1; + val += minorDist; + } + // vertical lines + val = -gridMaxW; + lineCount = 0; + while ( val <= gridMaxW ) { + if ( lineCount % ( _minorCount + 1 ) ) { + glVertex3f( val, DEPTH, -gridMaxH ); + glVertex3f( val, DEPTH, gridMaxH ); + } + lineCount += 1; + val += minorDist; + } + + // major lines + glColor4f( _lineColor.x(), _lineColor.y(), _lineColor.z(), 0.1f ); + glLineWidth( 2.0f ); + // horizontal + val = -gridMaxH; + while ( val <= gridMaxH ) { + glVertex3f( -gridMaxW, DEPTH, val ); + glVertex3f( gridMaxW, DEPTH, val ); + val += _majorDist; + } + // vertical + val = -gridMaxW; + while ( val <= gridMaxW ) { + glVertex3f( val, DEPTH, -gridMaxH ); + glVertex3f( val, DEPTH, gridMaxH ); + val += _majorDist; + } + + // center lines + glColor4f( _lineColor.x(), _lineColor.y(), _lineColor.z(), 0.2f ); + glLineWidth( 3.0f ); + // vertical + glVertex3f( 0.0f, DEPTH, -gridMaxH ); + glVertex3f( 0.0f, DEPTH, gridMaxH ); + // horizontal + glVertex3f( -gridMaxW, DEPTH, 0.0f ); + glVertex3f( gridMaxW, DEPTH, 0.0f ); + + glEnd(); + glPopAttrib(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::initGL() { + if ( GL_ID ) { + clearGL(); + } + GL_ID = glGenLists( 1 ); + glNewList( GL_ID, GL_COMPILE ); + // draw grid + plotGL(); + glEndList (); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::clearGL() { + glDeleteLists( GL_ID, 1 ); + GL_ID = 0; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::newContext() { + GL_ID = 0; + initGL(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLGroundPlane::setLineColor( float r, float g, float b ) { + _lineColor.set( r, g, b ); + initGL(); + } + + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLGroundPlane.h b/src/Menge/MengeCore/SceneGraph/GLGroundPlane.h new file mode 100644 index 00000000..90643e8a --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLGroundPlane.h @@ -0,0 +1,210 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLGroundPlane.h + * @brief The definition of a grid visualization of the ground plane. + */ + +#ifndef __GL_GROUND_PLANE_H__ +#define __GL_GROUND_PLANE_H__ + +#include "CoreConfig.h" +#include "GLNode.h" + +namespace Menge { + + namespace SceneGraph { + + /*! + * @brief A ground plane approximation -- z = 0, in world space. + * + * The ground plane is a rectangular piece, centered on the origin, with user-specified + * finite extent. It is rendered as a grid of lines with a heavy center line, medium + * major lines, and light minor lines. + */ + class MENGE_API GLGroundPlane: public GLNode { + public: + /*! + * @brief Constructor. + * + * @param width The extent of the plane along the world's x-axis. + * @param height The extent of the plane along the world's y-axis. + * @param majorDist The distance between major axis lines. + * @param minorCount The number of minor lines between major axis lines. + */ + GLGroundPlane( float width, float height, float majorDist, int minorCount ); + + /*! + * @brief Destructor. + */ + ~GLGroundPlane(void); + + /*! + * @brief Updates the OpenGL constructs for the grid when the context changes. + */ + void newContext(); + + /*! + * @brief Report the width of the ground plane (extent along world x-axis). + * + * @returns The plane segment's width. + */ + float getWidth() const { return _width; } + + /*! + * @brief Sets the width (the extent along the world's x-axis) of the plane. + * + * @param w The width, in world space units, of the plane. + */ + void setWidth( float w ); + + /*! + * @brief Report the height of the ground plane (extent along world y-axis). + * + * @returns The plane segment's height. + */ + float getHeight() const { return _height; } + + /*! + * @brief Sets the height (the extent along the world's y-axis) of the plane. + * + * @param h The height, in world space units, of the plane. + */ + void setHeight( float h ); + + /*! + * @brief Report the distance between major lines. + * + * @returns The distance between major lines on the plane. + */ + float getMajorDistance() const { return _majorDist; } + + /*! + * @brief Sets the distance between major lines. + * + * @param dist The distance between major lines on the plane. + */ + void setMajorDistance( float dist ); + + /*! + * @brief Report the number of minor lines between major lines. + * + * @returns The number of minor lines between major lines. + */ + int getMinorCount() const { return _minorCount; } + + /*! + * @brief Sets the number of minor lines between major lines. + * + * @param count The number of minor lines between major lines. + */ + void setMinorCount( int count ); + + /*! + * @brief Set the main color for the ground's lines. + * + * @param r The red component of the color (in the range [0, 1] ). + * @param g The green component of the color (in the range [0, 1] ). + * @param b The blue component of the color (in the range [0, 1] ). + */ + void setLineColor( float r, float g, float b ); + + /*! + * @brief Causes the plane to be drawn into the current OpenGL context. + * + * @param select Indicates if it is being drawn for selection purposes + * (true) or visualization (false). + */ + void drawGL( bool select=false ); + + private: + /*! + * @brief The width of the plane. The extent of the plane along the + * world's x-axis. + */ + float _width; + + /*! + * @brief The height of the plane. The extent of the plane along the + * world's y-axis. + */ + float _height; + + /*! + * @brief The distance between the medium-weight, major grid lines. + */ + float _majorDist; + + /*! + * @brief The number of light-weight, minor grid lines between major grid lines. + */ + int _minorCount; + + /*! + * @brief Emits the GL commands that draw the grid. + */ + void plotGL(); + + /*! + * @brief Initializes the OpenGL state necessary for drawing the plane. + * Should only be called after a valid OpenGL context has been + * created. + */ + void initGL(); + + /*! + * @brief Frees up the plane's OpenGL resources from the current context. + */ + void clearGL(); + + /*! + * @brief Identifier for this plane's OpenGL display list. Each plane + * gets its own display list. + */ + unsigned int GL_ID; + + /*! + * @brief The line color for this plane. + */ + Vector3 _lineColor; + }; + + } // namespace SceneGraph +} // namespace Menge +#endif // __GL_GROUND_PLANE_H__ diff --git a/src/Menge/MengeCore/SceneGraph/GLLight.cpp b/src/Menge/MengeCore/SceneGraph/GLLight.cpp new file mode 100644 index 00000000..4d00a9f1 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLLight.cpp @@ -0,0 +1,108 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GLLight.h" +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + //////////////////////////////////////////////////////////////// + // Implementation of GLLight + //////////////////////////////////////////////////////////////// + + GLLight::GLLight() { + setDefaults(); + } + + //////////////////////////////////////////////////////////////// + + void GLLight::setDefaults() { + _diff[0] = _diff[1] = _diff[2] = _diff[3] = 1.f; + _pos[0] = _pos[1] = _pos[2] = 1.f; + _pos[3] = 0.0; // directional light + } + + //////////////////////////////////////////////////////////////// + + void GLLight::setColor( float r, float g, float b, float a ) { + _diff[0] = r; + _diff[1] = g; + _diff[2] = b; + _diff[3] = a; + } + + //////////////////////////////////////////////////////////////// + + void GLLight::setPosition( float x, float y, float z, float w ) { + _pos[0] = x; + _pos[1] = y; + _pos[2] = z; + if ( w >= 0.f ) { + _pos[3] = w; + } + } + + //////////////////////////////////////////////////////////////// + + void GLLight::setLightType( LightType lightType ) { + switch( lightType ) { + case POINT: + _pos[3] = 1.f; + break; + case DIRECTIONAL: + _pos[3] = 0.f; + break; + } + } + + //////////////////////////////////////////////////////////////// + + void GLLight::initGL( int i, LightSpace space ) const { + if ( _space == space ) { + glEnable( GL_LIGHT0 + i ); + glLightfv( GL_LIGHT0 + i, GL_DIFFUSE, &_diff[0] ); + glLightfv( GL_LIGHT0 + i, GL_POSITION, &_pos[0] ); + // todo: add ambient and specular + //glLightfv( GL_LIGHT0 + i, GL_AMBIENT, &_ambient[0] ); + //glLightfv( GL_LIGHT0 + i, GL_SPECULAR, &_specular[0] ); + } + } + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLLight.h b/src/Menge/MengeCore/SceneGraph/GLLight.h new file mode 100644 index 00000000..393b4c9e --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLLight.h @@ -0,0 +1,189 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLLight.h + * @brief A simple light for defining OpenGL lighting + * properties. + */ + +#ifndef __GL_LIGHT_H__ +#define __GL_LIGHT_H__ + +#include "CoreConfig.h" +#include + +namespace Menge { + + namespace SceneGraph { + /*! + * @brief The OpenGL light class. Defines a light for the + * basic OpenGL pipeline. + */ + class MENGE_API GLLight { + public: + /*! + * @brief Defines the space of the camera: world or camera. + * + * If world, the camera is fixed to the world. + * If camera, it is fixed to the camera and moves with the camera. + */ + enum LightSpace { + WORLD, + CAMERA + }; + + /*! + * @brief Defines the type of the light: point or directional. + * + * If the light is point light, it acts like a single point + * source originating from the position. If the light is a + * directional light, it is a light source, infinitely far away + * oriented in the direction of the vector defined by the + * light position. + */ + enum LightType { + POINT, + DIRECTIONAL + }; + + /*! + * @brief Default constructor + */ + GLLight(); + + /*! + * @brief Sets the default light parameters + */ + void setDefaults(); + + /*! + * @brief Sets the light color. + * + * @param r The red component of the light's diffuse color. + * Must lie in the range [0, 1] + * @param g The green component of the light's diffuse color. + * Must lie in the range [0, 1] + * @param b The blue component of the light's diffuse color. + * Must lie in the range [0, 1] + * @param a The alpha component of the light's diffuse color. + * Must lie in the range [0, 1] + */ + void setColor( float r, float g, float b, float a=1.0 ); + + /*! + * @brief Sets the light color. + * + * @param x The x-value of the light's position. + * @param y The y-value of the light's position. + * @param z The z-value of the light's position. + * @param w The w-value of the light's position. It determines + * the light type (point or directional). If the value is + * 0, the light is set to directional, if > 0 it is set to + * point, if < 0, it remains unchanged. + */ + void setPosition( float x, float y, float z, float w=-1.f ); + + /*! + * @brief Sets the light type + * + * @param lightType The enumeration specifying either POINT or + * DIRECTIONAL light. + */ + void setLightType( LightType lightType ); + + /*! + * @brief Sets the space of the camera + * + * @param space The space for the camera. + */ + void setSpace( LightSpace space ) { _space = space; } + + /*! + * @brief + */ + + /*! + * @brief Initializes the corresponding OpenGL light + * + * @param i The GL identifier for this light, such that + * this light is GL_LIGHTi. + * @param space The space being initialized. If the light is + * defined in a different space, then it shouldn't + * execute itself + */ + void initGL( int i, LightSpace space=WORLD ) const; + + + protected: + /*! + * @brief The diffuse color of the light. It includes + * the red, green, blue and alpha values. + */ + float _diff[4]; + + /*! + * @brief The position of the light. It includes the + * x, y, z and type values. If type is 0, the light + * is directional, otherwise it is a point light. + */ + float _pos[4]; + + /*! + * @brief Space of the light + */ + LightSpace _space; + }; + + /*! + * @brief An STL vector of GLLight objects. + */ + typedef std::vector< GLLight > GLLightVector; + + /*! + * @brief An iterator for the GLLightVector. + */ + typedef GLLightVector::iterator GLLightVectorItr; + + /*! + * @brief A const iterator for the GLLightVector. + */ + typedef GLLightVector::const_iterator GLLightVectorCItr; + } // namespace SceneGraph +} // namespace Menge +#endif // __GL_LIGHT_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLNode.cpp b/src/Menge/MengeCore/SceneGraph/GLNode.cpp new file mode 100644 index 00000000..fa6a11d5 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLNode.cpp @@ -0,0 +1,153 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GLNode.h" + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR GLNode + /////////////////////////////////////////////////////////////////////////// + + GLNode::GLNode( GLDagNode * parent ):_parent(0x0), _visible( true ) { + if ( parent ) { + parent->addChild( this ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + GLNode::~GLNode() { + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR GLDagNode + /////////////////////////////////////////////////////////////////////////// + + GLDagNode::GLDagNode( GLDagNode * parent ):GLNode(parent), _children(0x0), _childCount(0) { + } + + /////////////////////////////////////////////////////////////////////////// + + GLDagNode::~GLDagNode() { + if ( _children ) { + for ( size_t i = 0; i < _childCount; ++i ) { + delete _children[i]; + } + delete [] _children; + } + } + + /////////////////////////////////////////////////////////////////////////// + + // This isn't the most efficient memory management, time-wise, but if you assume + // that the construction of the graph is pre-processing then it optimizes evaluation over construction + void GLDagNode::addChild( GLNode * child ) { + GLNode ** newChildren = new GLNode *[ _childCount + 1 ]; + for ( size_t i = 0; i < _childCount; ++i ) { + newChildren[i] = _children[i]; + } + newChildren[ _childCount ] = child; + ++_childCount; + if ( _children ) delete [] _children; + _children = newChildren; + child->setParent( this ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::drawGL( bool select ) { + for ( size_t i = 0; i < _childCount; ++i ) { + _children[i]->drawGL( select ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::getWorldMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::getWorldInverseMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldInverseMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::getParentMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldInverseMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::getParentInverseMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldInverseMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLDagNode::newContext() { + for ( size_t i = 0; i < _childCount; ++i ) { + _children[i]->newContext(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLNode.h b/src/Menge/MengeCore/SceneGraph/GLNode.h new file mode 100644 index 00000000..1dd16bfc --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLNode.h @@ -0,0 +1,297 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLNode.h + * @brief The basic scene graph node. Any object which can be placed + * into the scene graph is an instance or sub-class of this node. + */ + +#ifndef __GLNODE_H__ +#define __GLNODE_H__ + +#include "CoreConfig.h" +#include +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + class GLDagNode; + + /*! + * @brief An abstact class -- a generic, scene graph node. + * + * A GLNode can be included in a hierarchy, but cannot take + * children. It is the basic entity that forms the "graph" + * of the scene graph. It cannot be added to the scene + * but must be sub-classed. + */ + class MENGE_API GLNode { + public: + /*! + * @brief Constructor. + * + * @param parent A pointer to the optional parent node in the + * graph. + */ + GLNode( GLDagNode * parent=0x0 ); + + /*! + * @brief Virtual destructor. + */ + virtual ~GLNode(); + + /*! + * @brief Sets the visible state of the node. + * + * A node which is not visible does not draw in the scene. + * Nor does any child or child-tree that the node has. + * + * @param state The desired visible state. True for a visible + * node that will be drawn, false for invisible. + */ + void setVisible( bool state ) { _visible = state; } + + /*! + * @brief Causes this node to draw itself to the scene. + * + * This is a purely virtual function. Every node in the + * graph *must* implement this function. + * + * @param select Determines if the draw call is being performed + * for the purpose of selection (true) or for visualization + * (false). + */ + virtual void drawGL( bool select=false ) = 0; + + /*! + * @brief Allows the node to recreate any unique OpenGL objects + * based on the acquisition of a new OpenGL context. + * + * This should be over-ridden by nodes that have their own + * unique OpenGL constructs (display lists, textures, etc.) + */ + virtual void newContext() { return; } + + /*! + * @brief Returns a pointer to the node's parent (possibly NULL). + * + * @returns A pointer to a parent node -- if no parent, it returns NULL (0x0). + */ + GLDagNode * getParent() { return _parent; } + + friend class GLDagNode; + protected: + /*! + * @brief Assigns this node to a parent GLDagNode. + * + * Nodes should be linked by calling GLDagNode::addChild. + * + * @param p The pointer to the new parent node. + */ + void setParent( GLDagNode * p ) { _parent = p; } + + /*! + * @brief The GLDagNode that serves as this node's parent. + */ + GLDagNode * _parent; + + /*! + * @brief The visibility state of this node. If visible (true) the node + * and its children will be drawn into the scene, if invisible (false) + * it will not be drawn. + */ + bool _visible; + }; + + /*! + * @brief An STL list of GLNode objects. + */ + typedef std::list GLNodeList; + + /*! + * @brief An iterator for the GLNodeList. + */ + typedef GLNodeList::iterator GLNodeListItr; + + /*! + * @brief A const iterator for the GLNodeList. + */ + typedef GLNodeList::const_iterator GLNodeListCItr; + + /*! + * @brief The node that provides the basis for a "hierarchy" in the scene graph. + * + * The scene graph is, ultimately, not truly a graph. It is a directed + * acyclic graph, best thought of as a tree with the GLScene at the root and + * all other nodes inserted into sub-strees below the GLScene. + * + * The GLDagNode serves as the basis for this. It is a GLNode that can accept + * children, providing the mechanism for creating trees + */ + class MENGE_API GLDagNode : public GLNode { + public: + /*! + * @brief Constructor. + * + * @param parent A pointer to the optional parent node in the + * graph. + */ + GLDagNode( GLDagNode * parent=0x0 ); + + /*! + * @brief Virtual destructor. + */ + virtual ~GLDagNode(); + + /*! + * @brief Adds a child node to this node. + * + * Nodes can be linked either by calling GLNode::setParent or GLDagNode::addChild + * + * @param child The node to add as a child to this node. + */ + void addChild( GLNode * child ); + + /*! + * @brief Performs any work to recreate OpenGL constructs for this + * node and its children nodes. + */ + virtual void newContext(); + + /*! + * @brief Causes this node's child nodes to draw themselves to the scene. + * + * @param select Determines if the draw call is being performed + * for the purpose of selection (true) or for visualization + * (false). + */ + virtual void drawGL( bool select=false ); + + /*! + * @brief Reports the local object transform matrix. + * + * By definition, because this node can provide no transformation + * its transform matrix is the identity matrix. + * + * @param mat The 4x4 matrix into which the identity matrix is set. + */ + virtual void getMatrix( Matrix4x4 & mat ) { mat.identity(); } + + /*! + * @brief Reports the local object inverse transform matrix. + * + * By definition, because this node can provide no transformation + * its inverse transform matrix is the identity matrix. + * + * @param mat The 4x4 matrix into which the identity matrix is set. + */ + virtual void getInverseMatrix( Matrix4x4 & mat ) { mat.identity(); } + + /*! + * @brief Reports the world object transform matrix. + * + * This is the concatenation of all transforms experienced by this + * node and any node in its ancestors up to the GLSCene. This is + * essentially the transform that transforms elements in this + * object's space into world space. + * + * @param mat The 4x4 matrix into which the world matrix is set. + */ + virtual void getWorldMatrix( Matrix4x4 & mat ); + + /*! + * @brief Reports the world object inverse transform matrix. + * + * This is the concatenation of all transforms experienced by this + * node and any node in its ancestors up to the GLSCene. This is + * essentially the transform that transforms elements in world space + * into this object's space. + * + * @param mat The 4x4 matrix into which the inverse world matrix is set. + */ + virtual void getWorldInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief The world matrix of this node's parent matrix (see GLDagNode::getWorldMatrix) + * + * @param mat The 4x4 matrix into which the result is written. + * If this node has no parent matrix, the identity matrix is stored. + */ + virtual void getParentMatrix( Matrix4x4 & mat ); + + /*! + * @brief The inverse world matrix of this node's parent matrix (see GLDagNode::getWorldInverseMatrix) + * + * @param mat The 4x4 matrix into which the result is written. + * If this node has no parent matrix, the identity matrix is stored. + */ + virtual void getParentInverseMatrix( Matrix4x4 & mat ); + + protected: + /*! + * @brief An array of child GLNodes. + */ + GLNode ** _children; + + /*! + * @brief The number of child nodes this node contains. + */ + size_t _childCount; + }; + + /*! + * @brief An STL list of GLDagNode objects. + */ + typedef std::list GLDagNodeList; + + /*! + * @brief An iterator for the GLDagNodeList. + */ + typedef GLDagNodeList::iterator GLDagNodeListItr; + + /*! + * @brief A const iterator for the GLDagNodeList. + */ + typedef GLDagNodeList::const_iterator GLDagNodeListCItr; + + } // namespace SceneGraph +} // namespace Menge +#endif // __GLNODE_H__ diff --git a/src/Menge/MengeCore/SceneGraph/GLScene.cpp b/src/Menge/MengeCore/SceneGraph/GLScene.cpp new file mode 100644 index 00000000..3bd964f9 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLScene.cpp @@ -0,0 +1,179 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GLScene.h" +#include "graphCommon.h" +#include "GLCamera.h" +#include "Select.h" +#include + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR GLScene + /////////////////////////////////////////////////////////////////////////// + + GLScene::GLScene():_uiContext(0x0) { + } + + /////////////////////////////////////////////////////////////////////////// + GLScene::~GLScene() { + GLNodeListItr itr = _nodes.begin(); + for ( ; itr != _nodes.end(); ++itr ) { + delete (*itr); + } + + SystemListItr sItr = _systems.begin(); + for ( ; sItr != _systems.end(); ++sItr ) { + delete (*sItr); + } + + if ( _uiContext ) delete _uiContext; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLScene::finish() { + SystemListItr sItr = _systems.begin(); + for ( ; sItr != _systems.end(); ++sItr ) { + (*sItr)->finish(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLScene::newGLContext() { + GLNodeListItr itr = _nodes.begin(); + for ( ; itr != _nodes.end(); ++itr ) { + (*itr)->newContext(); + } + if ( _uiContext ) { + _uiContext->newGLContext(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLScene::drawGL( const GLCamera & camera, const GLLightVector & lights, int vWidth, int vHeight ) { + glLoadIdentity(); + camera.setGLView(); + int LIGHT_COUNT = (int)lights.size(); + for ( int i = 0; i < LIGHT_COUNT; ++i ) { + lights[ i ].initGL( i, GLLight::WORLD ); + } + + GLNodeListItr itr = _nodes.begin(); + + for ( ; itr != _nodes.end(); ++itr ) { + (*itr)->drawGL( false ); + } + + if ( _uiContext ) { + _uiContext->drawGL( vWidth, vHeight ); + } + + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLScene::selectGL( const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ) { + if ( _uiContext ) { + return _uiContext->selectGL( this, camera, vWidth, vHeight, selectPoint ); + } + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLScene::updateScene( float time ) { + bool redraw = false; + SystemListItr itr = _systems.begin(); + for ( ; itr != _systems.end(); ++itr ) { + redraw = (*itr)->updateScene( time ) || redraw; + } + if ( _uiContext ) _uiContext->update(); + return redraw; + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLScene::addNode( GLNode * node, GLDagNode * parent ) { + if ( !parent ) { + _nodes.push_back( node ); + } else { + parent->addChild( node ); + } + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLScene::addSystem( System * system ) { + _systems.push_back( system ); + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLScene::setContext( Context * context ) { + if ( _uiContext ) { + _uiContext->deactivate(); + delete _uiContext; + } + _uiContext = context; + _uiContext->activate(); + } + + /////////////////////////////////////////////////////////////////////////// + + ContextResult GLScene::handleMouse( SDL_Event & e ) { + if ( _uiContext ) return _uiContext->handleMouse( e ); + return ContextResult( false, false ); + } + + /////////////////////////////////////////////////////////////////////////// + + ContextResult GLScene::handleKeyboard( SDL_Event & e ) { + if ( _uiContext ) return _uiContext->handleKeyboard( e ); + return ContextResult( false, false ); + } + + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/GLScene.h b/src/Menge/MengeCore/SceneGraph/GLScene.h new file mode 100644 index 00000000..d37cfe1c --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/GLScene.h @@ -0,0 +1,207 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLScene.h + * @brief The definition of the scene -- the root of the directed, + * acyclic scene graph. + * + * It contains transforms, instances, lights, etc. It does *not* contain + * a camera. That is part of the viewer. + */ + +// TODO: determine if the camera should be part of the scene or viewer. + +#ifndef __GLSCENE_H__ +#define __GLSCENE_H__ + +#include "CoreConfig.h" + +#include "GLNode.h" +#include "System.h" +#include "Context.h" +#include "GLLight.h" + +#include + + +namespace Menge { + + namespace SceneGraph { + + class GLCamera; + + /*! + * @brief The class which contains the entire drawable scene. + */ + class MENGE_API GLScene { + public: + /*! + * @brief Default constructor. + */ + GLScene(); + + /*! + * @brief Destructor. + */ + ~GLScene(); + + /*! + * @brief Informs the scene that it is done being used. + * + * This gives the scene the chance to free up memory and stop whatever + * processes it may have been using (e.g., flushing caches, etc.) + * Typically just called by the viewer at the conclusion of visualization. + * More particularly, it gives the scene's systems to clean up and conclude + * their processes. + */ + void finish(); + + /*! + * @brief Allows the scene to recreate any unique OpenGL objects + * for all elements of the scene due to acquisition of a new + * OpenGL context. + */ + void newGLContext(); + + /*! + * @brief Causes the scene to draw into an open gl context + * + * @param camera The camera from which to derive the draw the scene. + * @param lights The lights to illuminate the 3D elements. + * @param vWidth The viewport width, in pixels, used in text overlay. + * @param vHeight The viewport height, in pixels, used in text overlay. + */ + void drawGL( const GLCamera & camera, const GLLightVector & lights, int vWidth, int vHeight ); + + /*! + * @brief Draws the selectable elements of the scene in preparation for selection. + * + * This uses the OpenGL selection context to perform active selection of elements + * in the scene. + * + * @param camera The camera from which to derive the draw the scene. + * @param vWidth The viewport width, in pixels, used in text overlay. + * @param vHeight The viewport height, in pixels, used in text overlay. + * @param selectPoint The point in screen space at which selection should occur. + * @returns True if the selection changed, false otherwise. + */ + bool selectGL( const GLCamera & camera, int vWidth, int vHeight, int * selectPoint ); + + /*! + * @brief Updates the state of the scene graph to the global time + * + * @param time The time for which the scene should be drawn. + * @returns A boolean reporting if a redraw is necessary (true) or not (false). + */ + bool updateScene( float time ); + + /*! + * @brief Add a node to the scene (with an optional parent) + * + * A node is added to the scene. If no parent is specified, the node is a child + * of the scene directly. Otherwise, it is a child of the parent. + * NOTE: No test is performed to confirm that the parent already exists in the + * scene. It is the responsibility of the caller to confirm that this is the case. + * + * @param node The node to add to the scene. + * @param parent The optional parent node. + * @returns Indication if the addition was successful (true) or not (false). + * Currently, this function always returns true. + */ + bool addNode( GLNode * node, GLDagNode * parent = 0x0 ); + + /*! + * @brief Adds a System to the scene. + * + * @param system The system to add to the scene. + * @returns True if the system is successfully added, false otherwise. + * In this implementation, it is *always* successful. + */ + bool addSystem( System * system ); + + /*! + * @brief Sets the context the scene will use to handle UI events. + * + * If the scene already has a context assigned, that context will be + * deactivated and *deleted*. + * + * @param context The scene's context. + */ + void setContext( Context * context ); + + /*! + * @brief Allows the scene to respond to a mouse event. + * + * @param e An instance of a mouse event. + * @returns An instance of a ContextResult, reporting whether the event has + * been handled and whether a redraw is necessary. + */ + ContextResult handleMouse( SDL_Event & e ); + + /*! + * @brief Allows the scene to respond to a keyboard event. + * + * @param e An instance of a keyboard event. + * @returns An instance of a ContextResult, reporting whether the event has + * been handled and whether a redraw is necessary. + */ + ContextResult handleKeyboard( SDL_Event & e ); + + friend class SelectContext; + private: + /*! + * @brief List of animation systems + */ + SystemList _systems; + + /*! + * @brief List of nodes which form the graph. Specifically, the nodes + * that are direct children of the scene. + */ + GLNodeList _nodes; + + /*! + * @brief UI context for handling events. + */ + Context * _uiContext; + }; + + } // namespace SceneGraph +} // namespace Menge +#endif //__GLSCENE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/ManagedData.h b/src/Menge/MengeCore/SceneGraph/ManagedData.h new file mode 100644 index 00000000..96b5ed0b --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/ManagedData.h @@ -0,0 +1,250 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ManagedData.h + * @brief The interface for handling resources from a disk system. + * + * ManagedData are heavy-weight on-disk resources. They are managed in the + * sense that they are only read from the disk once and stored in memory as + * a single instance. If multiple entities need the same on-disk resource, + * they share the underlying data in opaque containers. + */ + +#ifndef __MANAGED_DATA_H__ +#define __MANAGED_DATA_H__ + +#include "CoreConfig.h" +#include +#include + +namespace Menge { + + /*! + * @brief The interface for managed data (essentially smart poitners). + */ + class MENGE_API ManagedData { + public: + /*! + * @brief Constructor. + */ + ManagedData():_refCount(0){} + + /*! + * @brief Virtual destructor. + * + * Sub-classes of ManagedData, upon their destruction, must remove themselves + * from the resource set. It does this by performing a call to + * removeResource with appropriate template values and parameters. + * See ImageData::~ImageData as an example. + */ + virtual ~ManagedData(){} + + /*! + * @brief Increment references to the managed data. + * + * Any object that carries a pointer to managed data should call this function + * when acquiring and storing a pointer to that data. + * + * @returns The total number of references. + */ + int incRef() { return ++_refCount; } + + /*! + * @brief Decrement references to the managed data. + * + * Any object that carries a pointer to managed data should call this function + * upon destruction (thereby removing its reference from the managed data's reference + * count. + * + * @returns The number of remaining references. + */ + int decRef() { return --_refCount; } + + /*! + * @brief Reports if the data is referenced. + * + * Any object that carries a pointer to managed data, after dereferencing itself + * upon destruction, should determine if it is no longer referenced and delete + * the object if this function returns true. NOTE: this is not thread-safe. + * + * @returns True if the underlying managed data is no longer referenced, false + * otherwise. + */ + bool isUnreferenced() const { return _refCount == 0; } + + protected: + /*! + * @brief The number of data wrappers using this managed data. + */ + int _refCount; + }; + + /*! + * @brief A wrapper for managed data - automatically handles referencing + * and deletion of managed data. + * + * Any class that uses managed data directly (i.e., a class derived from + * ManagedData) should sub-class the ManagedData wrapper and implement its + * interface. The wrapper will automatically take care of reference counts. + */ + template < class TData > + class ManagedDataWrapper { + public: + /*! + * @brief Constructor. + * + * All classes which must call this constructor in their own constructors. + * See Image::Image for an example. + * + * @param data A pointer to an instance of ManagedData. + */ + ManagedDataWrapper( TData * data ) { + data->incRef(); + _data = data; + } + + /*! + * @brief Technically, decrements the data's reference count + * and garbage collects it when necessary. + * + * Sub-classes of ManagedDataWrapper should call this in their destructor + * after destorying all the rest of their memory. + * See Image::~Image for an example. + */ + void freeData() { + if ( _data->decRef() == 0 ) { + delete _data; + } + } + + protected: + /*! + * @brief The managed data for this wrapper. + */ + TData * _data; + }; + + // These templated functions serve as the basis for loading new instances of a resource (or + // grabbing them from the cached database.) + // + // To use them the derived class needs to satisfy the following requirements: + // 1. The class, Data, must have a PUBLIC static member: std::map< std::string, TData * > + // This class is a map that maps filenames to pointers to the corresponding loaded + // data. If the filename is not a key in this map, then the data has never been loaded + // 2. You must provide a function: Data * readData( const std::string ) + // This function constructs a new Data, reads the file and populates the data file, + // ADDS THE DATA FILE TO THE MAP, and returns the pointer to the data. + // 3. The wrapper class, T, must instantiate using TData * as the only argument with the + // constructor. + // + // If I do this, then any final user can simply call "T * myT = loadT( fileName );" And get + // a pointer to the data contained in the fileName which prevents duplicate loading and + // automatically tracks references so when all the T's that reference a particular TData + // are destroyed. + + /*! + * @brief Templated function for acquiring a managed data resource from its name. + * + * @param name The name of the on-disk resource. + * @param map The mapping from name to in-memory resource. + * @returns A pointer to the ManagedData instance if it is in memory, NULL otherwise. + */ + template< typename TData > + TData * getResource( const std::string & name, std::map< std::string, TData * > & map ) { + if ( map.find( name ) == map.end() ) { + return 0x0; + } else { + return map[ name ]; + } + } + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Templated function for loading a managed data resource. + * + * For each type of managed data and its wrapper, a function should exist that + * simply calls this function, templated on the wrapper and managed data types + * providing the name and the managed data reader function. See Image for an example. + * + * @param fileName The name of the on-disk resource. + * @param reader A pointer to the resource reading function. + * @returns A pointer to the wrapper for the managed data. NULL if the + * resource couldn't be acquired. + */ + template< typename T, typename TData> + T* loadManagedData( const std::string & fileName, TData * (*reader)(const std::string & ) ) { + TData * data = getResource( fileName, TData::RESOURCES ); + if ( data == 0x0 ) { + data = (*reader)( fileName ); + if ( data != 0x0 ) { + TData::RESOURCES[ fileName ] = data; + } + } + if ( data == 0x0 ) { + return 0x0; + } + return new T( data ); + } + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Tempalted function for removing a resource from the managed databse. + * + * This *should* be called by the managed data instance in its destructor. + * The data is no longer valid and should need to be reloaded before re-use. + * + * @param data A pointer to the managed data. + * @param map The map of names to manage data instances of this type. + */ + template < typename TData > + void removeResource( TData * data, std::map< std::string, TData * > & map ) { + // remove self from the resources set + typename std::map< std::string, TData *>::iterator itr = map.begin(); + for ( ; itr != map.end(); ++itr ) { + if ( itr->second == data ) { + map.erase( itr ); + break; + } + } + } +} // namespace Menge + +#endif diff --git a/src/Menge/MengeCore/SceneGraph/Select.cpp b/src/Menge/MengeCore/SceneGraph/Select.cpp new file mode 100644 index 00000000..3b8fc775 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Select.cpp @@ -0,0 +1,119 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Select.h" +#include "graphCommon.h" +#include + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Selectable + /////////////////////////////////////////////////////////////////////////// + + const unsigned int Selectable::BUFFER_SIZE = 16384; + unsigned int * Selectable::_buffer = new unsigned int[ Selectable::BUFFER_SIZE ]; + unsigned int Selectable::ID = 1; + Selectable * Selectable::_selectedObject = 0x0; + unsigned int Selectable::_selectedName = 0; + SelectableVector Selectable::_selectables; + + /////////////////////////////////////////////////////////////////////////// + + Selectable::Selectable():_id(ID), _selected(false) { + ++ID; + _selectables.push_back( this ); + } + + /////////////////////////////////////////////////////////////////////////// + + void Selectable::loadSelectName() const { + glLoadName( _id ); + } + + /////////////////////////////////////////////////////////////////////////// + + void Selectable::selectStart() { + glSelectBuffer( BUFFER_SIZE, _buffer ); + glRenderMode( GL_SELECT ); + glInitNames(); + glPushName( 0 ); // if the hit is zero, it means nothing is selected + } + + /////////////////////////////////////////////////////////////////////////// + + bool Selectable::selectEnd() { + int hitCount = glRenderMode( GL_RENDER ); + + unsigned int oldSelName = _selectedName; + Selectable * oldSelection = _selectedObject; + // deselect the currently selected node + if ( _selectedObject ) { + _selectedObject->_selected = false; + } + + _selectedObject = 0x0; + _selectedName = 0; + if ( hitCount ) { + _selectedName = _buffer[3]; + unsigned int selDepth = _buffer[1]; + int baseIndex = 4; + for ( int i = 1; i < hitCount; ++i ) { + if ( _buffer[ baseIndex + 1 ] < selDepth ) { + _selectedName = _buffer[ baseIndex + 3 ]; + selDepth = _buffer[ baseIndex + 1 ]; + } + baseIndex += 4; + } + if ( _selectedName > 0 && _selectedName <= (unsigned int)_selectables.size() ) { + _selectedObject = _selectables[ _selectedName - 1 ]; + _selectedObject->_selected = true; + } + } + + return _selectedObject != oldSelection || oldSelName != _selectedName; + } + + /////////////////////////////////////////////////////////////////////////// + + + } // namespace SceneGraph + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/Select.h b/src/Menge/MengeCore/SceneGraph/Select.h new file mode 100644 index 00000000..e67fc981 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Select.h @@ -0,0 +1,215 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Select.h + * @brief Functionality to make nodes in the scene graph selectable by mouse clicking. + */ + +#ifndef __SELECT_H__ +#define __SELECT_H__ + +#include "CoreConfig.h" +#include +#include + +namespace Menge { + + namespace SceneGraph { + + /*! + * @brief The class interface for selectable objects -- objects which can be selectedc + * in the OpenGL context by clicking on them. + */ + class MENGE_API Selectable { + public: + /*! + * @brief Constructor. + */ + Selectable(); + + /*! + * @brief Performs the OpenGL task to make this object selectable. + */ + void loadSelectName() const; + + /*! + * @brief Returns this object's globally unique *selection* id. + * + * @returns The selection id - a positive value. + */ + unsigned int getID() const { return _id; } + + /*! + * @brief A dummy function that makes Selectable polymorphic. + * It enables the use of dynamic_cast. Otherwise, it is a no-op. + */ + virtual void dummy() { return; } + + /*! + * @brief Retrives a pointer to the currently selected node. + * + * @returns A pointer to the selected object -- NULL if no object is selected. + */ + static Selectable * getSelectedObject() { return _selectedObject; } + + /*! + * @brief Returns the "name" of the currently selected object. + * + * In this case, "name" refers to the OpenGL identifier. It corresponds to + * a *selectable* object's id (see Selectable::getID). + * + * @returns The OpenGL name (selectable id) of the currently selected object. + * If no object is selected, it returns zero. + */ + static unsigned int getSelectedName() { return _selectedName; } + + /*! + * @brief Clears the current selection + */ + static void clearSelectedObject() { + if ( _selectedObject ) _selectedObject->_selected = false; + _selectedObject = 0x0; + _selectedName = 0; + } + + /*! + * @brief Forces an arbitrary selectable to be selected + * + * @param obj A selectable object to set as selected. + */ + static void setSelectedObject( Selectable * obj ) { + clearSelectedObject(); + _selectedName = obj->_id; + _selectedObject = obj; + obj->_selected = true; + } + + /*! + * @brief The selection set up. + * + * To perform selection, this needs to be called prior to drawing the scene of + * selectable objects. + */ + static void selectStart(); + + /*! + * @brief The selection take down. + * + * When performing selection, after calling Selectable::selectStart and drawing the + * scene, this must be called to conclude the selection process. + * + * @returns A boolean reporting if the selection *changed* (true) or not (false). + */ + static bool selectEnd(); + + /*! + * @brief Reports the next available selection name + */ + static unsigned int nextSelectName() { return ID; } + + protected: + /*! + * @brief Globally unique OpenGL name for selection. + */ + unsigned int _id; + + /*! + * @brief Reports if this node is selcted. + * + * This can be used by contexts or objects that change how they are drawn based + * on selection state. + */ + bool _selected; + + private: + /*! + * @brief An OpenGL construct. The size of a buffer to hold selection candiadtes. + */ + static const unsigned int BUFFER_SIZE; + + /*! + * @brief The OpenGL buffer for holding selection candidates. + */ + static unsigned int * _buffer; + + /*! + * @brief A gobal counter of the number of selectable objects in the scene. + * + * Used to assign a new globally unique selection id to the next Selectable. + */ + static unsigned int ID; + + /*! + * @brief The currently selected object + * + * This system currently only supports selection of one item at a time. + * TODO: support multiple selection as required. + */ + static Selectable * _selectedObject; + + /*! + * @brief The OpenGL Selection name of the currently selected object. + */ + static unsigned int _selectedName; + + /*! + * @brief Set of all selectable objects (their ids serve as indices into the list). + */ + static std::vector< Selectable * > _selectables; + + }; + + /*! + * @brief An STL Vector of Selectable objects. + */ + typedef std::vector< Selectable * > SelectableVector; + + /*! + * @brief An iterator for the SelectableVector. + */ + typedef SelectableVector::iterator SelectableVectorItr; + + /*! + * @brief A const iterator for the SelectableVector. + */ + typedef SelectableVector::const_iterator SelectableVectorCItr; + + } // namespace SceneGraph +} // namespace Menge +#endif // __SELECT_H__ diff --git a/src/Menge/MengeCore/SceneGraph/System.h b/src/Menge/MengeCore/SceneGraph/System.h new file mode 100644 index 00000000..a2596647 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/System.h @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +// A system drives attributes of a graph +// Before drawing a graph, systems get evaluated to make sure what's being drawn +// is "correct" and "updated". +// Systems are relatively lazy. Their update can be called, but only if the system KNOWS it needs +// to be updated, will it update. + +/*! + * @file System.h + * @brief The mechanism for evolving a scene w.r.t. time. + */ + +#ifndef __SYSTEM_H__ +#define __SYSTEM_H__ + +#include "CoreConfig.h" +#include "MengeException.h" +#include +#include + +namespace Menge { + + namespace SceneGraph { + + /*! + * @brief Exception class for indicating that a system is done. + * + * When a system will no longer change the the scene with calls to + * System::updateScene, it throws the SystemStopException. The caller + * is responsible for catching and reacting appropriately. + */ + class MENGE_API SystemStopException : public Menge::MengeException { + public: + /*! + * @brief Default constructor. + */ + SystemStopException() : Menge::MengeException() {} + }; + + /*! + * @brief An animation system. Responsible for updating the scene based + * based on increasing time values. + * + * This is a purely virtual class. It must be sub-classed to be used. + */ + class MENGE_API System { + public: + /*! + * @brief Default constructor. + */ + System() {} + + /*! + * @brief Virtual destructor. + */ + virtual ~System() {} + + /*! + * @brief Finalizing function for the system. + * + * When the viewer wants to exit, it calls this method on the scene to give the + * scene any last minute things it needs to do (such as outputting data) + * The scene calls the systems finish method. + */ + virtual void finish(){} + + /*! + * @brief Updates the state of the scene graph with the global time. + * + * @param time The time for which the system should be set. + * @returns True if the system changed the scene such that it should be redrawn. + */ + virtual bool updateScene( float time ) = 0; + }; + + /*! + * @brief An STL list of System objects. + */ + typedef std::list< System * > SystemList; + + /*! + * @brief An iterator for the SystemList. + */ + typedef SystemList::iterator SystemListItr; + + /*! + * @brief A const iterator for the SystemList. + */ + typedef SystemList::const_iterator SystemListCItr; + + } // namespace SceneGraph +} // namespace Menge +#endif // __SYSTEM_H__ diff --git a/src/Menge/MengeCore/SceneGraph/TextWriter.cpp b/src/Menge/MengeCore/SceneGraph/TextWriter.cpp new file mode 100644 index 00000000..503d575c --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/TextWriter.cpp @@ -0,0 +1,370 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "TextWriter.h" +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR TextWriter + /////////////////////////////////////////////////////////////////////////// + + TextWriter * TextWriter::_instance = 0x0; + std::string TextWriter::DEFAULT_FONT = std::string( "arial.ttf" ); + const int TextWriter::DEFAULT_SIZE = 20; + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::setDefaultFont( const std::string & fontName ) { + DEFAULT_FONT = fontName; + } + + /////////////////////////////////////////////////////////////////////////// + + TextWriter * TextWriter::Instance() { + if ( _instance == 0x0 ) { + _instance = new TextWriter(); + } + return _instance; + } + + /////////////////////////////////////////////////////////////////////////// + + TextWriter::TextWriter(): _width(640), _height(480), _fontName(""), _textID(0), _textQuadID(0) { + TTF_Init(); + setFont( DEFAULT_FONT ); + assert( _fonts.size() > 0 && "Unable to load font" ); + _defColor[0] = _defColor[1] = _defColor[2] = 0.f; + _defColor[3] = 0.75f; + } + + /////////////////////////////////////////////////////////////////////////// + + TextWriter::~TextWriter() { + closeFonts(); + glDeleteLists( _textQuadID, 1 ); + glDeleteTextures( 1, &_textID ); + TTF_Quit(); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::newGLContext() { + makeTextDList(); + makeGLTexture(); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::printAlignText( const std::string & text, Alignment alignment, int fontSize, float hpad, float vpad, bool currColor, bool transparent ) { + float w, h; + textSize( text, fontSize, w, h ); + + float left = hpad, bottom = vpad; // defaults to LEFT, BOTTOM alignment + if ( alignment & VCENTER ) { + bottom = ( _height - h ) / 2.0f; + } else if ( alignment & TOP ) { + bottom = ( _height - h - vpad); + } + if ( alignment & HCENTER ) { + left = ( _width - w ) / 2.0f; + } else if ( alignment & RIGHT ) { + left = ( _width - w - hpad); + } + printText( text, left, bottom, fontSize, currColor, transparent ); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::printText( const std::string & text, Alignment alignment, float anchorX, float anchorY, int fontSize, bool currColor, bool transparent ) { + float w, h; + textSize( text, fontSize, w, h ); + + float left = anchorX, bottom = anchorY; // defaults to LEFT, BOTTOM alignment + if ( alignment & VCENTER ) { + bottom = anchorY - h / 2.0f; + } else if ( alignment & TOP ) { + bottom = anchorY - h; + } + if ( alignment & HCENTER ) { + left = anchorX - w / 2.0f; + } else if ( alignment & RIGHT ) { + left = anchorX - w; + } + + printText( text, left, bottom, fontSize, currColor, transparent ); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::printAnchorText( const std::string & text, float anchorX, float anchorY, float xWeight, float yWeight, int fontSize, bool currColor, bool transparent ) { + float w, h; + textSize( text, fontSize, w, h ); + + float left = anchorX - xWeight * w; + float bottom = anchorY - yWeight * h; + + printText( text, left, bottom, fontSize, currColor, transparent ); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::printText( const std::string & text, float left, float bottom, int fontSize, bool currColor, bool transparent ) { + TTF_Font * font = getFont( fontSize ); + if ( font == 0x0 ) return; + int lineCount = 1; + int nlIndex = (int)text.find_first_of( "\n" ); + while ( nlIndex > -1 ) { + lineCount += 1; + nlIndex = (int)text.find_first_of( "\n", nlIndex + 1 ); + } + + // set up orthogonal view + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, _width, 0.0, _height, -1.0f, 1.0f ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT ); + glDisable( GL_DEPTH_TEST ); + + glBindTexture( GL_TEXTURE_2D, _textID ); + if ( transparent ) { + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; + } + glDisable( GL_LIGHTING ); + glEnable( GL_TEXTURE_2D ); + + if ( !currColor ) { + glColor4fv( &_defColor[0] ); + } + // for each line + // Render the line + // put the surface into the texture + // render the quad + int startIndex = 0; + nlIndex = (int)text.find_first_of( "\n" ); + while ( nlIndex > -1 ) { + --lineCount; + int length = nlIndex - startIndex; + if ( length ) { + std::string testStr = text.substr( startIndex, length ); + printLine( font, testStr.c_str(), left, bottom, lineCount ); + startIndex = nlIndex + 1; + nlIndex = (int)text.find_first_of( "\n", startIndex ); + } + } + int length = nlIndex - startIndex; + if ( length ) { + std::string testStr = text.substr( startIndex, length ); + --lineCount; + printLine( font, testStr.c_str(), left, bottom, lineCount ); + } + + glPopAttrib(); + glPopMatrix(); + // draw a character + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::resize( int w, int h ) { + _width = w; + _height = h; + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::textSize( const std::string & text, int fontSize, float & textWidth, float & textHeight ) { + TTF_Font * font = getFont( fontSize ); + if ( font == 0x0 ) { + textWidth = 0.f; + textHeight = 0.f; + return; + } + int w, h; + textHeight = 0.f; + textWidth = 0.f; + int startIndex = 0; + int nlIndex = (int)text.find_first_of( "\n" ); + while ( nlIndex > -1 ) { + int length = nlIndex - startIndex; + std::string testStr = text.substr( startIndex, length ); + TTF_SizeText( font, testStr.c_str(), &w, &h ); + textHeight += (float)h; + if ( (float)w > textWidth ) textWidth = (float)w; + startIndex = nlIndex + 1; + nlIndex = (int)text.find_first_of( "\n", startIndex ); + } + int length = (int)text.length() - startIndex; + std::string testStr = text.substr( startIndex, length ); + TTF_SizeText( font, testStr.c_str(), &w, &h ); + textHeight += (float)h; + if ( (float)w > textWidth ) textWidth = (float)w; + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::printLine( TTF_Font * font, const char * text, float left, float bottom, int lineNum ) { + static const SDL_Color foregroundColor = { 255, 255, 255 }; + SDL_Surface * surf = TTF_RenderText_Blended( font, text, foregroundColor ); + sdlSurfaceToGLTex( surf ); + glPushMatrix(); + /// scale and translate the quad + // translate so that the left-bottom corner is at (left, bottom + height * lineCount ) + // I'm assuming that each line, for a given font size, is the same height + glTranslatef( left, bottom + surf->h * lineNum, 0.f ); + glScalef( (float)surf->w, (float)surf->h, 1.f ); + glCallList( _textQuadID ); + glPopMatrix(); + SDL_FreeSurface(surf); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::closeFonts() { + FontMapItr itr = _fonts.begin(); + for ( ; itr != _fonts.end(); ++itr ) { + TTF_CloseFont( itr->second ); + } + _fonts.clear(); + } + + /////////////////////////////////////////////////////////////////////////// + + bool TextWriter::setFont( const std::string &fontName ) { + if ( _fontName != fontName ) { + // Only do the work if it's really a change + TTF_Font * newFont = TTF_OpenFont( fontName.c_str(), DEFAULT_SIZE ); + if ( newFont ) { + closeFonts(); + _fonts.clear(); + _fonts[ DEFAULT_SIZE ] = newFont; + _fontName = fontName; + return true; + } + } + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::setDefaultColor( float r, float g, float b, float alpha ) { + _defColor[ 0 ] = r; + _defColor[ 1 ] = g; + _defColor[ 2 ] = b; + _defColor[ 3 ] = alpha; + } + /////////////////////////////////////////////////////////////////////////// + + TTF_Font * TextWriter::getFont( int size ) { + if ( size <= 0 ) return 0x0; + if ( _fonts.find( size ) == _fonts.end() ) { + TTF_Font * newFont = TTF_OpenFont( _fontName.c_str(), size ); + if ( newFont ) { + _fonts[ size ] = newFont; + } + } + return _fonts[ size ]; + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::makeTextDList() { + _textQuadID = glGenLists( 1 ); + glNewList( _textQuadID, GL_COMPILE ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.f, 1.f ); + glVertex3f( 0.f, 0.f, 0.0f ); + glTexCoord2f( 1.f, 1.f ); + glVertex3f( 1.f, 0.f, 0.0f ); + glTexCoord2f( 1.f, 0.f ); + glVertex3f( 1.f, 1.f, 0.0f ); + glTexCoord2f( 0.f, 0.f ); + glVertex3f( 0, 1.f, 0.0f ); + glEnd(); + glEndList(); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::makeGLTexture() { + if ( _textID != 0 ) glDeleteTextures( 1, &_textID ); + glGenTextures( 1, &_textID ); + } + + /////////////////////////////////////////////////////////////////////////// + + void TextWriter::sdlSurfaceToGLTex( SDL_Surface *surf ) { + assert( surf->format->BytesPerPixel == 4 && "Texture not RGBA" ); + assert( _textID > 0 && "Can't bind surface to a texture of 0" ); + + GLint nOfColors = surf->format->BytesPerPixel; + GLenum texture_format; + if (surf->format->Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, _textID ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, + texture_format, GL_UNSIGNED_BYTE, surf->pixels ); + + } + + } // namespace SceneGraph +} // namespace Menge diff --git a/src/Menge/MengeCore/SceneGraph/TextWriter.h b/src/Menge/MengeCore/SceneGraph/TextWriter.h new file mode 100644 index 00000000..6e19b19f --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/TextWriter.h @@ -0,0 +1,363 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TextWriter.h + * @brief Functionality for writing text on the OpenGL context. + */ + +#ifndef __TEXT_WRITER_H__ +#define __TEXT_WRITER_H__ + +#include "CoreConfig.h" +#include "image.h" +#include +#include "SDL/SDL_ttf.h" +#include + +namespace Menge { + + namespace SceneGraph { + /*! + * @brief An STL map to map from font size to SDL font class. + */ + typedef std::map< int, TTF_Font * > FontMap; + + /*! + * @brief An iterator for the FontMap. + */ + typedef FontMap::iterator FontMapItr; + + /*! + * @brief A const iterator for the FontMap. + */ + typedef FontMap::const_iterator FontMapCItr; + + /*! + * @brief A singleton class responsible for writing text to an OpenGL context + * + * It has numerous functions for drawing text. It typically works in screen space, + * where the upper, left-hand corner is (0, 0). + */ + class MENGE_API TextWriter { + /*! + * @brief The name of the default font to use. + */ + static std::string DEFAULT_FONT; + + /*! + * @brief The default font size. + */ + static const int DEFAULT_SIZE; + public: + /*! + * @brief Sets the default font to use. + * + * @param fontName The path to the font to use. + */ + static void setDefaultFont( const std::string & fontName ); + + /*! + * @brief Enumeration for controlling text alignment. + */ + enum Alignment { + NO_ALIGN = 0x0, // 0 + VCENTER = 0x1, // 1 + TOP = 0x2, // 2 + BOTTOM = 0x4, // 4 + LEFT = 0x8, // 8 + LEFT_CENTER = 0x9, // 9 + LEFT_TOP = 0xA, // 10 + LEFT_BOTTOM = 0xC, // 12 + RIGHT = 0x10, // 16 + RIGHT_CENTER = 0x11, // 17 + RIGHT_TOP = 0x12, // 18 + RIGHT_BOTTOM = 0x14, // 20 + HCENTER = 0x20, // 32 + CENTERED = 0x21, // 33 + CENTER_TOP = 0x22, // 34 + CENTER_BOTTOM = 0x24 // 36 + }; + + /*! + * @brief Acquire pointer to a singleton text writer instance. + */ + static TextWriter * Instance(); + + /*! + * @brief Resets the text writer's context-dependent data + * Called when the OpenGL context is called + */ + void newGLContext(); + + /*! + * @brief Print the given text with an alignment relative to the given anchor point + * + * @param text The string to draw. + * @param alignment The alignment, relative to the screen. + * @param anchorX The x-position of the anchor point (in screen coords). + * @param anchorY The y-position of the anchor point (in screen coords). + * @param fontSize The size of the text, in pixels. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + * @param transparent Indicates if the text is super-imposed over the screen or given a + * matte. True --> superimposed, false --> matted. + */ + void printText( const std::string & text, Alignment alignment, float anchorX, float anchorY, int fontSize, bool currColor=false, bool transparent=true ); + + /*! + * @brief Print the given text to the screen at the given coordinates + * + * @param text The string to draw. + * @param left The position of the left extent of the text (in screen coords). + * @param bottom The position of the bottom extent of the text (in screen coords). + * @param fontSize The size of the text, in pixels. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + * @param transparent Indicates if the text is super-imposed over the screen or given a + * matte. True --> superimposed, false --> matted. + */ + void printText( const std::string & text, float left, float bottom, int fontSize, bool currColor=false, bool transparent=true ); + + /*! + * @brief Print the given text to the screen with the specified alignment + * + * @param text The string to draw. + * @param alignment The alignment, relative to the screen. + * @param fontSize The size of the text, in pixels. + * @param hpad The amount of horizontal padding to apply in the horizontal alignment + * direction. For example, if left aligned, it goes on the left, if + * right aligned, the padding is on the right. + * @param vpad The amount of vertical padding to apply in the vertical direction. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + * @param transparent Indicates if the text is super-imposed over the screen or given a + * matte. True --> superimposed, false --> matted. + */ + void printAlignText( const std::string & text, Alignment alignment, int fontSize, float hpad, float vpad, bool currColor=false, bool transparent=true ); + + /*! + * @brief Prints the text anchored to the position. The relationship to the anchor + * depends on the anchor weights. It interpolates them from bottom left + * top top right. + * @param text The string to draw. + * @param anchorX The x-position of the anchor point (in screen coords). + * @param anchorY The y-position of the anchor point (in screen coords). + * @param xWeight The horizontal weight in the range [0, 1]. 0--> left, 1 --> right alignment. + * @param yWeight The vertical weight in the range [0, 1]. 0--> bottom, 1 --> top alignment. + * @param fontSize The size of the text, in pixels. + * @param currColor Indicates if the current opengl color should be used (true) or the + * text writer's default color should be used (false). + * @param transparent Indicates if the text is super-imposed over the screen or given a + * matte. True --> superimposed, false --> matted. + */ + void printAnchorText( const std::string & text, float anchorX, float anchorY, float xWeight, float yWeight, int fontSize, bool currColor=false, bool transparent=true ); + + /*! + * @brief Reports the size, in pixels, the given text will consume on the screen, + * given current font and indicated font size. + * + * @param text The string to draw. + * @param fontSize The size of the font (in points). + * @param textWidth The width of the text will be stored in this value. + * @param textHeight The height of the text will be stored in this value. + */ + void textSize( const std::string & text, int fontSize, float & textWidth, float & textHeight ); + + /*! + * @brief Inform the text writer that the viewport has resized. + * + * This must be called by the viewer when the viewport resizes. This information is how the + * TextWriter correctly interprets alignment. + * + * @param w The viewport width (in pixels). + * @param h The viewport height (in pixels). + */ + void resize( int w, int h ); + + /*! + * @brief Reports TextWriter's belief of the viewport width. + * + * @returns The effective viewport width the TextWrtier is using. + */ + inline int getViewWidth() const { return _width; } + + /*! + * @brief Reports TextWriter's belief of the viewport width. + * + * @returns The effective viewport width the TextWrtier is using. + */ + inline int getViewHeight() const { return _height; } + + /*! + * @brief Changes the font family + * + * The first font is loaded at the default size + * If it is unable to load the font, the old family is left in place + * + * @param fontName The name of the font family to use. + * @returns True if the font was successfully loaded, false otherwise. + * If false, it uses the default font. + */ + bool setFont( const std::string & fontName ); + + /*! + * @brief Sets the default font color. + * + * @param r The red component of the color. + * @param g The green component of the color. + * @param b The blue component of the color. + * @param alpha The alpha component of the color. + * Default value is 1.0. + */ + void setDefaultColor( float r, float g, float b, float alpha=1.f ); + + /*! + * @brief A utility function to map from screen to image coordinates. + * + * The screen coordiantes have the origin in the top, left corner. + * Image coordinates have the origin at the *bottom*, left corner. + * + * @param y The vertical position in screen coordinates. + * @returns The vertical position in corresponding image coordinates. + */ + inline int flipY( int y ) { return _height - y; } + + // TODO: Support multiple families of fonts + + protected: + /*! + * @brief Returns a pointer to a font for the given size. + * + * @param size The desired size of the font. + * @returns A pointer to a font instance at the desired size. + * If size is negative, NULL is returned. + */ + TTF_Font * getFont( int size ); + + /*! + * @brief Close out the current set of fonts. + */ + void closeFonts(); + + /*! + * @brief Protected constructor. No instantiation allowed. + */ + TextWriter(); + + /*! + * @brief Protected destructor + */ + ~TextWriter(); + + /*! + * @brief The singleton pointer. + */ + static TextWriter* _instance; + + /*! + * @brief The width of the viewport the TextWriter considers when computing text positions. + */ + int _width; + + /*! + * @brief The height of the viewport the TextWriter considers when computing text positions. + */ + int _height; + + /*! + * @brief Generate the display list for the quad upon which text is printed. + */ + void makeTextDList(); + + /*! + * @brief Generate the OpenGL texture object for the text. + */ + void makeGLTexture(); + + /*! + * @brief Set the surface upon which the text has been rendered to a texture. + * + * @param surf The surface upon which the text has been rendered. + */ + void sdlSurfaceToGLTex( SDL_Surface * surf ); + + /*! + * @brief The work necessary to print a single line of text. + * + * The text is displayed relative to the anchor point of an entire *block* of text, + * (left, bottom), withthe text extending above and to the right of the anchor point. + * + * @param font The font to render the text. + * @param text The text to draw. + * @param left The horizontal value of the anchor point. + * @param bottom The vertical value of the anchor point. + * @param lineNum The line number of the given text (zero-indexed). Used to offset + * this line relative to the anchor point. + */ + void printLine( TTF_Font * font, const char * text, float left, float bottom, int lineNum ); + + /*! + * @brief Map of all font sizes for this font face. + */ + FontMap _fonts; + + /*! + * @brief Name of font. + */ + std::string _fontName; + + /*! + * @brief Texture object for texturing the rendered text + */ + GLuint _textID; + + /*! + * @brief Call list for the text surface + */ + GLuint _textQuadID; + + /*! + * @brief The default font color. + */ + float _defColor[4]; + + }; + } // namespace SceneGraph +} // namespace Menge +#endif //__TEXT_WRITER_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/Transform.cpp b/src/Menge/MengeCore/SceneGraph/Transform.cpp new file mode 100644 index 00000000..cb0e05b6 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Transform.cpp @@ -0,0 +1,115 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Transform.h" +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Transform + /////////////////////////////////////////////////////////////////////////// + + Transform::Transform( GLDagNode * parent ): GLDagNode(parent) { + } + + /////////////////////////////////////////////////////////////////////////// + + void Transform::getWorldMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + Matrix4x4 thisMat(false), pMat(false); + getMatrix( thisMat ); + _parent->getWorldMatrix( pMat ); + mat.product( thisMat, pMat ); + } else { + getMatrix( mat ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Transform::getWorldInverseMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + Matrix4x4 pIMat(false), thisIMat(false); + _parent->getWorldInverseMatrix( pIMat ); + getInverseMatrix( thisIMat ); + mat.product( pIMat, thisIMat ); + } else { + getInverseMatrix( mat ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Transform::getParentMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Transform::getParentInverseMatrix( Matrix4x4 & mat ) { + if ( _parent ) { + _parent->getWorldInverseMatrix( mat ); + } else { + mat.identity(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Transform::drawGL( bool select ) { + if ( _visible ) { + glPushMatrix(); + Matrix4x4 mat(false); + _xform.getMatrix( mat ); + glMultMatrixf( mat.getFlattened() ); + GLDagNode::drawGL( select ); + glPopMatrix(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + } // namespace SceneGraph +} // namespace Menge diff --git a/src/Menge/MengeCore/SceneGraph/Transform.h b/src/Menge/MengeCore/SceneGraph/Transform.h new file mode 100644 index 00000000..85b716ee --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/Transform.h @@ -0,0 +1,252 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Transform.h + * @brief Scene graph node which carries rigid transformations. + */ +#ifndef __TRANSFORM_H__ +#define __TRANSFORM_H__ + +#include "CoreConfig.h" +#include "GLNode.h" +#include "XformMatrix.h" + +namespace Menge { + + namespace SceneGraph { + /*! + * @brief Scene graph node which applies transforms to nodes. + * + * The Transform uses the XformMatrix to compute the transformation math. + * See XformMatrix for the details of the math. + */ + class MENGE_API Transform : public GLDagNode { + public: + /*! + * @brief Constructor. + * + * @param parent A pointer to the optional parent node in the + * graph. + */ + Transform( GLDagNode * parent=0x0 ); + + /*! + * @brief Set the translation of this node. + * + * @param vec The 3D position of the transform. + */ + inline void setTranslation( const Vector3 & vec ) { _xform.setTranslation( vec ) ; } + + /*! + * @brief Offset the translation of this node. + * + * @param vec The change to position of this node. + */ + inline void addTranslation( const Vector3 & vec ) { _xform.addTranslation( vec ); } + + /*! + * @brief Set the scale of this node. + * + * @param vec The desired scale of this node. + */ + inline void setScale( const Vector3 & vec ) { _xform.setScale( vec ); } + + /*! + * @brief Set the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in degrees. + */ + inline void setRotationDeg( const Vector3 & vec ) { _xform.setRotationDeg( vec ); } + + /*! + * @brief Set the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in radians. + */ + inline void setRotationRad( const Vector3 & vec ) { _xform.setRotationRad( vec ); } + + /*! + * @brief Offsets the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. In this case, each axis is + * summed independently. Generally, because these are Euler angles, this will + * will not lead to linear interpolation of orientation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in degrees. + */ + inline void addRotationDeg( const Vector3 & vec ) { _xform.addRotationDeg( vec ); } + + /*! + * @brief Offsets the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. In this case, each axis is + * summed independently. Generally, because these are Euler angles, this will + * will not lead to linear interpolation of orientation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in radians. + */ + inline void addRotationRad( const Vector3 & vec ) { _xform.addRotationRad( vec ); } + + /*! + * @brief Set the orientation of this node's rotation axis. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The orientation of the rotation axis around the x-, y-, + * and z-axes, respectively in degrees. + */ + inline void setRotAxisDeg( const Vector3 & vec ) { _xform.setRotAxisDeg( vec ); } + + /*! + * @brief Set the orientation of this node's rotation axis. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The orientation of the rotation axis around the x-, y-, + * and z-axes, respectively in radians. + */ + inline void setRotAxisRad( const Vector3 & vec ) { _xform.setRotAxisRad( vec ); } + + /*! + * @brief Reports the transform's translation value. + * + * @returns The translation of this matrix. + */ + const Vector3 & translation() const { return _xform._trans; } + + /*! + * @brief Reports the transform's orientation value. + * + * @returns The orientation of this matrix. + */ + const Vector3 & rotation() const { return _xform._rot; } + + /*! + * @brief Reports the transform's scale value. + * + * @returns The orientation of this matrix. + */ + const Vector3 & scale() const { return _xform._scale; } + + /*! + * @brief Sets the transformation to be dirty. + * + * The transform node tries to perform lazy math. Only re-computing + * matrices due to changes and required computation. Setting it to dirty + * will force matrix computation next time the matrix is needed. + */ + void setDirty() { _xform.setDirty(); } + + /*! + * @brief Returns the transform matrix created by this transform node. + * + * @param mat This matrix contains the matrix when done. + */ + inline void getMatrix( Matrix4x4 & mat ) { _xform.getMatrix( mat ); } + + /*! + * @brief Writes the transform's inverse matrix created by this transform node. + * + * @param mat This matrix contains the inverse matrix when done. + */ + inline void getInverseMatrix( Matrix4x4 & mat ) { _xform.getInverseMatrix( mat ); } + + /*! + * @brief Returns the world matrix of this node; the matrix that transforms points + * from this node's object space to world space. + * + * @param mat This matrix contains the world matrix when done. + */ + void getWorldMatrix( Matrix4x4 & mat ); + + /*! + * @brief Returns the world inverse matrix of this node; the matrix that transforms points + * from world space to this node's object space. + * + * @param mat This matrix contains the world inverse matrix when done. + */ + void getWorldInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief Returns this node's parent's world matrix. + * + * @param mat This matrix contains the parent matrix when done. + */ + void getParentMatrix( Matrix4x4 & mat ); + + /*! + * @brief Returns this node's parent's world inverse matrix. + * + * @param mat This matrix contains the parent's inverse matrix when done. + */ + void getParentInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief Causes this node's child nodes to draw themselves to the scene, transformed + * by this node's transformation matrix. + * + * @param select Determines if the draw call is being performed + * for the purpose of selection (true) or for visualization + * (false). + */ + virtual void drawGL( bool select=false ); + + protected: + /*! + * @brief The underlyilng transformation matrix associated with this transform node. + */ + XformMatrix _xform; + }; + } // namespace SceneGraph +} // namespace Menge +#endif // __TRANSFORM_H__ diff --git a/src/Menge/MengeCore/SceneGraph/XformMatrix.cpp b/src/Menge/MengeCore/SceneGraph/XformMatrix.cpp new file mode 100644 index 00000000..1f2f26c9 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/XformMatrix.cpp @@ -0,0 +1,201 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "XformMatrix.h" + +#include +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR XformMatrix + /////////////////////////////////////////////////////////////////////////// + + XformMatrix::XformMatrix():_trans(0.f, 0.f, 0.f), + _scale(1.f, 1.f, 1.f ), + _rot( 0.f, 0.f, 0.f ), + _rotAxis( 0.f, 0.f, 0.f ) { + setDirty(); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::setRotAxisDeg( const Vector3 & vec ) { + _rotAxis = vec * DEG_TO_RAD; + updateRotAxisMat(); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::setRotAxisRad( const Vector3 & vec ) { + _rot = vec; + updateRotAxisMat(); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::updateRotAxisMat() { + setDirty( MAT | IMAT ); + float cx = cosf( _rotAxis.x() ); + float cy = cosf( _rotAxis.y() ); + float cz = cosf( _rotAxis.z() ); + float sx = sinf( _rotAxis.x() ); + float sy = sinf( _rotAxis.y() ); + float sz = sinf( _rotAxis.z() ); + + _rotAxisMat.setRow( 0, cy*cz, cy*sz, -sy, 0 ); + _rotAxisMat.setRow( 1, sx*sy*cz - cx*sz, cx*cz + sx*sy*sz, sx*cy, 0 ); + _rotAxisMat.setRow( 2, sx*sz + cx*sy*cz, cx*sy*sz - sx*cz, cx*cy, 0 ); + _rotAxisMat.setRow( 3, 0, 0, 0, 1 ); + _rotAxisIMat.setAsTranspose( _rotAxisMat ); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::translationMatrix( Matrix4x4 & mat ) { + mat.identity(); + mat.setRow( 3, _trans ); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::translationInverseMatrix( Matrix4x4 & mat ) { + mat.identity(); + mat.setRow( 3, -_trans.x(), -_trans.y(), -_trans.z() ); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::scaleMatrix( Matrix4x4 & mat ) { + mat.identity(); + mat.setDiagonal( _scale ); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::scaleInverseMatrix( Matrix4x4 & mat ) { + mat.identity(); + mat.setDiagonal( 1.f / _scale.x(), 1.f / _scale.y(), 1.f / _scale.z() ); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::rotationMatrix( Matrix4x4 & mat ) { + if ( !isClean( ROT_MAT ) ) { + setClean( ROT_MAT ); + // assumes XYZ rotation + _rotMat.setRow( 3, 0.f, 0.f, 0.f, 1.f ); + _rotMat(0, 3) = _rotMat(1, 3) = _rotMat(2,3) = 0.f; + + float cx = cosf( _rot.x() ); + float sx = sinf( _rot.x() ); + float cy = cosf( _rot.y() ); + float sy = sinf( _rot.y() ); + float cz = cosf( _rot.z() ); + float sz = sinf( _rot.z() ); + + _rotMat(0, 0) = cz * cy; + _rotMat(0, 1) = cy * sz; + _rotMat(0, 2) = -sy; + _rotMat(1, 0) = cz * sx * sy - sz * cx; + _rotMat(1, 1) = sx * sy * sz + cx * cz; + _rotMat(1, 2) = sx * cy; + _rotMat(2, 0) = cz * cx * sy + sx * sz; + _rotMat(2, 1) = sz * cx * sy - sx * cz; + _rotMat(2, 2) = cx * cy; + } + + mat = _rotMat; + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::rotationInverseMatrix( Matrix4x4 & mat ) { + rotationMatrix( mat ); + mat.transpose(); + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::getMatrix( Matrix4x4 & mat ) { + // Matrix is a composition of 5 matrices: + // SCALE * rotAxisInverse * ROTATE * rotAxis * TRANSLATE + // re-written (with cached values) as: + // SCALE * PRE-ROTATE * ROTATE * POST-ROTATE * TRANSLATE + if ( !isClean( MAT ) ) { + setClean( MAT ); + + Matrix4x4 temp1(false), temp2(false), rotMat(false); + rotationMatrix( rotMat ); + temp1.scale( _scale, _rotAxisIMat ); + temp2.product3x3( rotMat, _rotAxisMat ); + _mat.product3x3( temp1, temp2 ); + _mat.translateRotation( _trans ); + } + mat = _mat; + } + + /////////////////////////////////////////////////////////////////////////// + + void XformMatrix::getInverseMatrix( Matrix4x4 & mat ) { + // Inverse matrix is a composition of 5 matrices: + // (SCALE * rotAxisInverse * ROTATE * rotAxis * TRANSLATE)^-1 + // re-written (with cached values) as: + // (SCALE * PRE-ROTATE * ROTATE * POST-ROTATE * TRANSLATE)^-1 + // = T^-1 * PRE-ROTATE * R^-1 * POST-ROTATE * S^-1 + // -- NOTE: PRE-ROTATE^-1 = POST-ROTATE (and vice versa) + if ( !isClean( IMAT ) ) { + setClean( IMAT ); + Matrix4x4 temp1(false), temp2(false), rotMat(false); + rotationInverseMatrix( rotMat ); + temp1.product3x3( _rotAxisIMat, rotMat ); + // the scale matrix can be left or right multiplied to the same effect + temp2.scaleRight( _scale, _rotAxisMat ); + _iMat.product3x3( temp1, temp2 ); + _iMat.translateRotationLeft( -_trans ); + } + mat = _iMat; + } + + /////////////////////////////////////////////////////////////////////////// + + } // namespace SceneGraph +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/XformMatrix.h b/src/Menge/MengeCore/SceneGraph/XformMatrix.h new file mode 100644 index 00000000..daf575f4 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/XformMatrix.h @@ -0,0 +1,355 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file XformMatrix.h + * @brief Defines the math of performing 3D transformation using a + * 4x4 homgeneous matrix. + */ + +#ifndef __XFORMMATRIX_H__ +#define __XFORMMATRIX_H__ + +#include "CoreConfig.h" +#include "graphCommon.h" +#include + +namespace Menge { + + namespace SceneGraph { + + class Transform; + + /*! + * @brief The transformation matrix. + * + * The transform matrix is the concatenation of *five* transformation matrices + * SCALE * ROT_AXIS^-1 * ROTATE * ROT_AXIS * TRANSLATE + * The scale, rotation, and translation matrices are self-explanatory. + * They account for the changes in size, rotation around the orign, and re-positioning + * of the node. The transform also defines a "rotation axis". The rotation + * values can be defined around an arbitrary axis, rather than the node's local + * space. One can think of the rotation axis as a pre-rotation. + */ + class MENGE_API XformMatrix { + public: + /*! + * @brief Default constructor - identity matrix. + */ + XformMatrix(); + + /*! + * @brief Set the translation of this node. + * + * @param vec The 3D position of the transform. + */ + void setTranslation( const Vector3 & vec ) { _trans = vec; setDirty( MAT | IMAT ); } + + /*! + * @brief Offset the translation of this node. + * + * @param vec The change to position of this node. + */ + void addTranslation( const Vector3 & vec ) { _trans += vec; setDirty( MAT | IMAT ); } + + /*! + * @brief Set the scale of this node. + * + * @param vec The desired scale of this node. + */ + void setScale( const Vector3 & vec ) { _scale = vec; setDirty( MAT | IMAT ); } + + /*! + * @brief Set the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in degrees. + */ + void setRotationDeg( const Vector3 & vec ) { _rot = vec * DEG_TO_RAD; setDirty(); } + + /*! + * @brief Set the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in radians. + */ + void setRotationRad( const Vector3 & vec ) { _rot = vec; setDirty(); } + + /*! + * @brief Offsets the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. In this case, each axis is + * summed independently. Generally, because these are Euler angles, this will + * will not lead to linear interpolation of orientation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in degrees. + */ + void addRotationDeg( const Vector3 & vec ) { _rot.SumScale( DEG_TO_RAD, vec ); setDirty(); } + + /*! + * @brief Offsets the orientation of this node. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. In this case, each axis is + * summed independently. Generally, because these are Euler angles, this will + * will not lead to linear interpolation of orientation. + * + * @param vec The rotations around the x-, y-, and z-axes, respectively + * in radians. + */ + void addRotationRad( const Vector3 & vec ) { _rot += vec; setDirty(); } + + /*! + * @brief Set the orientation of this node's rotation axis. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The orientation of the rotation axis around the x-, y-, + * and z-axes, respectively in degrees. + */ + void setRotAxisDeg( const Vector3 & vec ); + + /*! + * @brief Set the orientation of this node's rotation axis. + * + * Rotation is performed using Euler angles and the implict evaluation order + * of x-, then y-, and finally z-axis rotation. + * + * @param vec The orientation of the rotation axis around the x-, y-, + * and z-axes, respectively in radians. + */ + void setRotAxisRad( const Vector3 & vec ); + + /*! + * @brief Comptues the rotation p + */ + //void rotatePivotMatrix( Matrix4x4 & mat ); + /*! + * @brief Computes the translation matrix. + * + * @param mat Writes the translation matrix in the provided matrix. + */ + void translationMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the translation inverse matrix. + * + * @param mat Writes the inverse translation matrix in the provided matrix. + */ + void translationInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the scale matrix. + * + * @param mat Writes the scale matrix in the provided matrix. + */ + void scaleMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the inverse scale matrix. + * + * @param mat Writes the inverse scale matrix in the provided matrix. + */ + void scaleInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the rotation matrix. + * + * @param mat Writes the rotation matrix in the provided matrix. + */ + void rotationMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the inverse rotation matrix. + * + * @param mat Writes the inverse rotation matrix in the provided matrix. + */ + void rotationInverseMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the transformation matrix. + * + * @param mat Writes the matrix in the provided matrix. + */ + void getMatrix( Matrix4x4 & mat ); + + /*! + * @brief Computes the inverse transformation matrix. + * + * @param mat Writes the inverse matrix in the provided matrix. + */ + void getInverseMatrix( Matrix4x4 & mat ); + + friend class Transform; + + /*! + * @brief Print the matrix to the output stream. + * + * @param out The output stream. + * @param xformMat The transformation matrix to print to the output stream. + */ + friend Logger & operator << ( Logger & out, const XformMatrix & xformMat ); + + protected: + + /*! + * @brief The translation component of the transformation. + */ + Vector3 _trans; + + /*! + * @brief The scale component of the transformation. + */ + Vector3 _scale; + + /*! + * @brief The rotation component of the transformation. + * Euler angles in radians. + */ + Vector3 _rot; + + /*! + * @brief The rotation axis component of the transformation. + * Pre-rotation Euler angles in radians. + */ + Vector3 _rotAxis; + + /*! + * @brief Cached rotation axis matrix. + */ + Matrix4x4 _rotAxisMat; + + /*! + * @brief Cached inverse rotation axis matrix. + */ + Matrix4x4 _rotAxisIMat; + + /*! + * @brief Enumeration of dirty matrices. + * + * Used to intelligently compute matrices as necessary. + */ + enum MatrixBit { + ROT_MAT = 1, // rotation matrix + MAT = 2, // full matrix + IMAT = 4 // inverse matrix + }; + + /*! + * @brief An integer mask for determining which cached matrices are clean/dirty + * + * Works with the MatrixBit enumeration to determine which matrices need to be + * recomputed. + */ + int _clean; + + /*! + * @brief Cached rotation matrix. + */ + Matrix4x4 _rotMat; + + /*! + * @brief Cached transformation matrix. + */ + Matrix4x4 _mat; + + /*! + * @brief Cached inverse transformation matrix. + */ + Matrix4x4 _iMat; + + /*! + * @brief Update cached rotation axis matrices when component changes. + */ + void updateRotAxisMat(); + + /*! + * @brief Set all matrices dirty. + */ + inline void setDirty() { _clean = 0; } + + /*! + * @brief Set the matrix corresponding to the given bit dirty. + * + * @param bit The bit for the specific matrix to set dirty. Should + * be a MatrixBit enumeration value. + */ + inline void setDirty( int bit ) { _clean &= ~bit; } + + /*! + * @brief Set the matrix corresponding to the given bit dirty. + * + * @param bit The bit for the specific matrix to set dirty. + */ + inline void setDirty( MatrixBit bit ) { _clean &= (int)(~bit); } + + /*! + * @brief Reports if the indicated matrix is clean. + * + * @param bit The bit for the specific matrix to set dirty. + * @returns True if the matrix does NOT need recomputation, false otherwise. + */ + inline bool isClean( MatrixBit bit ) { return ( _clean & (int)bit ) != 0x0; } + + /*! + * @brief Sets the indicated matrix to be clean. + * + * @param bit The bit for the specific matrix to set clean. + */ + inline void setClean( MatrixBit bit ) { _clean |= (int)bit; } + + /*! + * @brief Sets the indicated matrix to be clean. + * + * @param bit The bit for the specific matrix to set clean. Should + * be a MatrixBit enumeration value. + */ + inline void setClean( int bit ) { _clean |= bit; } + }; + } // namespace SceneGraph +} // namespace Menge +#endif // __XFORMMATRIX_H__ diff --git a/src/Menge/MengeCore/SceneGraph/graphCommon.h b/src/Menge/MengeCore/SceneGraph/graphCommon.h new file mode 100644 index 00000000..5393764b --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/graphCommon.h @@ -0,0 +1,76 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file graphCommon.h + * @brief Various important pre-compiler directives for the scene graph. + */ + +#ifndef __GRAPH_COMMON_H__ +#define __GRAPH_COMMON_H__ + +#ifdef _WIN32 +#include +#endif +#include "GL/gl.h" +#include "Math/Matrix.h" +#include "Math/consts.h" +#include "mengeCommon.h" + +#ifndef GL_BGR +/*! + * @brief OpenGL constant for determing pixel order for 3-color textures. + */ +#define GL_BGR 0x80E0 +#endif + +#ifndef GL_BGRA +/*! + * @brief OpenGL constant for determing pixel order for 4-color textures. + */ +#define GL_BGRA 0x80E1 +#endif + +#ifndef GL_CLAMP_TO_EDGE +/*! + * @brief OpenGL constant for determing texture behavior. + */ +#define GL_CLAMP_TO_EDGE 0x812F +#endif + +#endif // __GRAPH_COMMON_H__ diff --git a/src/Menge/MengeCore/SceneGraph/image.cpp b/src/Menge/MengeCore/SceneGraph/image.cpp new file mode 100644 index 00000000..b0813668 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/image.cpp @@ -0,0 +1,220 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "image.h" +#include +#include "GLContextManager.h" + +namespace Menge { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR ImageData + /////////////////////////////////////////////////////////////////////////// + + std::map< std::string, ImageData * > ImageData::RESOURCES; + bool ImageData::IS_REGISTERED = false; + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::start() { + int flags = IMG_INIT_JPG | IMG_INIT_PNG; + int initted = IMG_Init( flags ); + if( ( initted & flags ) == 0x0) { + logger << Logger::ERR_MSG << "Failed to initialize png and jpg support! No images available!\n"; + // TODO: Put some flags in here that will silently suppress images + } else if ( ( initted & IMG_INIT_JPG ) == 0 ) { + logger << Logger::ERR_MSG << "Failed to initialize jpg support!\n"; + } else if ( ( initted & IMG_INIT_PNG ) == 0 ) { + logger << Logger::ERR_MSG << "Failed to initialize png support!\n"; + } + } + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::release() { + IMG_Quit(); + } + + /////////////////////////////////////////////////////////////////////////// + + ImageData::ImageData():ManagedData(),_useAlpha( false ), _texture( 0 ), _img( 0 ) { + if ( ! IS_REGISTERED ) { + GLContextManager::addCallback( &newGLContext ); + IS_REGISTERED = true; + } + } + + /////////////////////////////////////////////////////////////////////////// + + ImageData * readImageData( const std::string & fileName ) { + ImageData * data = new ImageData(); + + data->_img = IMG_Load( fileName.c_str() ); + if ( data->_img != 0x0 ) { + data->_useAlpha = data->_img->format->BytesPerPixel > 3; + ImageData::RESOURCES[ fileName ] = data; + } else { + delete data; + data = 0x0; + } + return data; + } + + /////////////////////////////////////////////////////////////////////////// + + int ImageData::getBpp() const { + return _useAlpha ? 32 : 24; + } + + /////////////////////////////////////////////////////////////////////////// + + ImageData::~ImageData() { + if ( _texture != 0 ) { + glDeleteTextures( 1, &_texture ); + _texture = 0; + } + if ( _img ) { + SDL_FreeSurface( _img ); + _img = 0x0; + } + removeResource< ImageData >( this, ImageData::RESOURCES ); + } + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::initGL() const { + unsigned int w = getWidth(); + unsigned int h = getHeight(); + + glGenTextures( 1, &_texture ); + glBindTexture( GL_TEXTURE_2D, _texture ); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + if ( _useAlpha ) { + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, + GL_BGRA, GL_UNSIGNED_BYTE, _img->pixels ); + } else { + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, w, h, 0, + GL_BGR, GL_UNSIGNED_BYTE, _img->pixels ); + } + + } + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::bind() const { + glBindTexture( GL_TEXTURE_2D, _texture ); + glEnable( GL_TEXTURE_2D ); + if ( _useAlpha ) { + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::drawGL() const { + glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT ); + bind(); + glDisable( GL_LIGHTING ); + glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0f, 1.0f ); + glVertex3f( 0.0f, 0.0f, 0.0f ); + glTexCoord2f( 1.0, 1.0f ); + glVertex3f( (GLfloat)getWidth(), 0.0f, 0.0f ); + glTexCoord2f( 1.0, 0.0f ); + glVertex3f( (GLfloat)getWidth(), (GLfloat)getHeight(), 0.0 ); + glTexCoord2f( 0.0, 0.0f ); + glVertex3f( 0.0f, (GLfloat)getHeight(), 0.0 ); + glEnd(); + glPopAttrib(); + } + + /////////////////////////////////////////////////////////////////////////// + + void ImageData::newGLContext() { + // I don't call glDeleteTexture because at this point, I assume + // that I've already lost it by changing contexts and merely need + // to recreate the gl texture. + std::map< std::string, ImageData * >::iterator itr = RESOURCES.begin(); + for ( ; itr != RESOURCES.end(); ++itr ) { + itr->second->initGL(); + } + + } + + /////////////////////////////////////////////////////////////////////////// + + unsigned char ImageData::getPixelAt( int x, int y ) const { + + int bpp = _img->format->BytesPerPixel; + unsigned char * p = static_cast< unsigned char * >(_img->pixels) + ( y * _img->pitch + x * bpp ); + + int out = 0; + for ( int i = 0; i < bpp; ++i ) { + out += p[ i ]; + } + out = out / bpp; + return static_cast< unsigned char >( out ); + + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Image + /////////////////////////////////////////////////////////////////////////// + + Image::Image( ImageData *data ): ManagedDataWrapper< ImageData >(data) { + } + + /////////////////////////////////////////////////////////////////////////// + + Image::~Image() { + freeData(); + } + + /////////////////////////////////////////////////////////////////////////// + + Image * loadImage( const std::string & fileName ) { + return loadManagedData< Image, ImageData>( fileName, &readImageData ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/SceneGraph/image.h b/src/Menge/MengeCore/SceneGraph/image.h new file mode 100644 index 00000000..9f7307e1 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/image.h @@ -0,0 +1,229 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file image.h + * @brief The interface for loading and using images in the scene graph. + */ + +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +#include "CoreConfig.h" +#include +#include "graphCommon.h" +#include "ManagedData.h" +#include +#include "SDL/SDL_image.h" + +namespace Menge { + + /*! + * @brief Manged image data (see ManagedData). + */ + class MENGE_API ImageData : public ManagedData { + public: + /*! + * @brief Mapping from image resources to its corresponding data. + */ + static std::map< std::string, ImageData * > RESOURCES; + + /*! + * @brief Determines if the ImageData::newGLContext has been registered. + */ + static bool IS_REGISTERED; + + /*! + * @brief The function to call when an OpenGL context has changed. + */ + static void newGLContext(); + + /*! + * @brief Initializes the image system. + * + * Must be called before images can be used. Essentially, it calls the + * SDL Image initialization + */ + static void start(); + + /*! + * @brief Called when done using images. + */ + static void release(); + + /*! + * @brief Constructor. + */ + ImageData(); + + /*! + * @brief Destructor. + */ + ~ImageData(); + + /*! + * @brief Returns the width of the image (in pixels). + * + * @returns The width of the image (in pixels). + */ + int getWidth() const { return _img->w; } + + /*! + * @brief Returns the height of the image (in pixels). + * + * @returns The height of the image (in pixels). + */ + int getHeight() const { return _img->h; } + + /*! + * @brief Reports the bits per pixel. + * + * @returns Either 24 or 32, depending on whether the image has an + * alpha channel (32) or not (24). + */ + int getBpp() const; + + /*! + * @brief Initializes the image for drawing in an OpenGL context. + */ + void initGL() const; + + /*! + * @brief Draws the image onto a quad, centered on the origin of the x-y plane. + */ + void drawGL() const; + + /*! + * @brief Binds the image to use as a texture in OpenGL. + */ + void bind() const; + + /*! + * @brief Loads the image from a file (specified by name) + * + * @param fileName The path to a valid image file. + * @returns A pointer to the underlying ImageData. If there is an + * error, NULL is returned. + */ + friend ImageData * readImageData( const std::string & fileName ); + + /*! + * @brief Returns the red channel of the image at the given pixel. + * + * @param x The x-coordinate of the pixel. + * @param y The y-coordinate of the pixel. + * @returns the red channel of the image at the given pixel. + */ + unsigned char getPixelAt( int x, int y ) const; + + private: + /*! + * @brief Indicates whether the image uses per-pixel alpha. + */ + bool _useAlpha; + + /*! + * @brief The OpenGL texture id for the image. + */ + mutable GLuint _texture; + + /*! + * @brief The SDL surface which contains the image data. + */ + SDL_Surface * _img; + }; + + + /*! + * @brief Wrapper for the managed ImageData. + */ + class MENGE_API Image : public ManagedDataWrapper< ImageData > { + public: + /*! + * @brief Construtor. + * + * @param data An instance of ImageData. + */ + Image( ImageData * data ); + + /*! + * @brief Destructor. + */ + ~Image(); + + /*! + * @brief Binds the image to use as a texture in OpenGL. + */ + void bind() const { _data->bind(); } + + /*! + * @brief Returns the image data. + * + * @returns A const pointer to the underlying image data. + */ + const ImageData * data() const { return _data; } + + /*! + * @brief Returns the width of the image (in pixels). + * + * @returns The width of the image (in pixels). + */ + int getWidth() const { return _data->getWidth(); } + + /*! + * @brief Returns the height of the image (in pixels). + * + * @returns The height of the image (in pixels). + */ + int getHeight() const { return _data->getHeight(); } + + + }; + + /*! + * @brief Given a filename, returns a pointer to an Image with that data. + * + * @param fileName The unique path to the image. + * @returns A pointer to an Image instance. If there is a problem loading + * the image, NULL is returned. The caller is responsible for + * deleting the pointer. + */ + MENGE_API Image * loadImage( const std::string & fileName ); +} // namespace Menge + +#endif // __IMAGE_H__ diff --git a/src/Menge/MengeCore/SceneGraph/shapes.cpp b/src/Menge/MengeCore/SceneGraph/shapes.cpp new file mode 100644 index 00000000..35ea94b2 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/shapes.cpp @@ -0,0 +1,295 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "shapes.h" +#include "GLContextManager.h" + +namespace Menge { + + namespace SceneGraph { + + void initShapes() { + Circle::init(); + Cylinder::init(); + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Shape primitives + /////////////////////////////////////////////////////////////////////////// + + void glSphere( int samples ) { + float * c = new float[ samples * 4 ]; + float * s = c + samples; + float * c_2 = s + samples; + float * s_2 = c_2 + samples; + + float angle = TWOPI / samples; + float angle2 = PI / (samples - 1); + for ( int i = 0; i < samples; ++i ) { + c[ i ] = cos( i * angle ); + s[ i ] = sin( i * angle ); + c_2[ i ] = cos( i * angle2 ); + s_2[ i ] = sin( i * angle2 ); + } + + // render sphere + glBegin( GL_TRIANGLE_FAN ); + glNormal3f( 0.f, 1.f, 0.f ); + glVertex3f( 0.f, 1.f, 0.f ); + float sx = s_2[ 1 ]; + float cx = c_2[ 1 ]; + + for ( int i = 0; i <= samples; ++i ) { + // vertical normal rotated around the x-axis (towards positive z) + // [ -sx cx 0 ]^T + // That rotated around vertical axis + // [ cysx cx -sxsy ] // this is both the normal and the position + int idx = i % samples; + float sy = s[idx]; + float cy = c[idx]; + glNormal3f( cy * sx, cx, -sx * sy ); + glVertex3f( cy * sx, cx, -sx * sy ); + } + glEnd(); + + // center strips + for ( int i = 1; i < samples - 1; ++i ) { + glBegin( GL_QUAD_STRIP ); + float cx1 = c_2[ i ]; + float sx1 = s_2[ i ]; + float cx2 = c_2[ i + 1 ]; + float sx2 = s_2[ i + 1 ]; + for ( int j = 0; j <= samples; ++j ) { + int idx = j % samples; + float sy = s[idx]; + float cy = c[idx]; + glNormal3f( cy * sx1, cx1, -sx1 * sy ); + glVertex3f( cy * sx1, cx1, -sx1 * sy ); + glNormal3f( cy * sx2, cx2, -sx2 * sy ); + glVertex3f( cy * sx2, cx2, -sx2 * sy ); + + } + glEnd(); + } + // bottom fan + glBegin( GL_TRIANGLE_FAN ); + glNormal3f( 0.f, -1.f, 0.f ); + glVertex3f( 0.f, -1.f, 0.f ); + sx = s_2[ samples - 1 ]; + cx = c_2[ samples - 1 ]; + + for ( int i = 0; i <= samples; ++i ) { + // vertical normal rotated around the x-axis (towards positive z) + // [ -sx cx 0 ]^T + // That rotated around vertical axis + // [ cysx cx -sxsy ] // this is both the normal and the position + int idx = i % samples; + float sy = s[idx]; + float cy = c[idx]; + glNormal3f( cy * sx, cx, -sx * sy ); + glVertex3f( cy * sx, cx, -sx * sy ); + } + glEnd(); + delete [] c; + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Circle Shape + /////////////////////////////////////////////////////////////////////////// + + bool Circle::IS_REGISTERED = false; + int Circle::GL_ID = 0; + + /////////////////////////////////////////////////////////////////////////// + + void Circle::newGLContext() { + GL_ID = glGenLists( 1 ); + + glNewList( GL_ID, GL_COMPILE ); + const int SAMPLE_COUNT = 24; + + // Simple circle + float dTheta = TWOPI / ( SAMPLE_COUNT - 1 ); + glBegin( GL_POLYGON ); + for ( int i = 0; i < SAMPLE_COUNT; ++i ) { + float theta = i * dTheta; + float x = cos( theta ); + float y = sin( theta ); + glVertex3f( x, 0.f, y ); + } + glEnd(); + + glEndList(); + } + + /////////////////////////////////////////////////////////////////////////// + + void Circle::init() { + if ( ! IS_REGISTERED ) { + GLContextManager::addCallback( &newGLContext ); + IS_REGISTERED = true; + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Circle::drawGL( bool select ) { + if ( _visible ) { + drawCircle( _radius, _r, _g, _b, 1.f, _style ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Circle::drawCircle( float radius, float r, float g, float b, float a, GLenum style ) { + glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_POLYGON_BIT ); + // set up drawing + glDisable( GL_TEXTURE_2D ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable( GL_LIGHTING ); + glPolygonMode( GL_FRONT_AND_BACK, style ); + glColor4f(r,g,b,a); + glPushMatrix(); + glScalef( radius, radius, radius ); + glCallList( GL_ID ); + glPopMatrix(); + glPopAttrib(); + } + + /////////////////////////////////////////////////////////////////////////// + + void Circle::drawUnit() { + glCallList( GL_ID ); + } + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR Cylinder Shape + /////////////////////////////////////////////////////////////////////////// + + bool Cylinder::IS_REGISTERED = false; + int Cylinder::GL_ID = 0; + + /////////////////////////////////////////////////////////////////////////// + + void Cylinder::newGLContext() { + GL_ID = glGenLists( 1 ); + + glNewList( GL_ID, GL_COMPILE ); + const int SAMPLE_COUNT = 24; + // Collect the points + + float points[ SAMPLE_COUNT ][2]; + float dTheta = TWOPI / ( SAMPLE_COUNT - 1 ); + for ( int i = 0; i < SAMPLE_COUNT; ++i ) { + float theta = i * dTheta; + float x = cos( theta ); + float y = sin( theta ); + points[ i ][ 0 ] = x; + points[ i ][ 1 ] = y; + } + + // Simple cylinder + // bottom face + glBegin( GL_POLYGON ); + glNormal3f( 0.f, -1.f, 0.f ); + for ( int i = SAMPLE_COUNT - 1; i >= 0; --i ) { + glVertex3f( points[ i ][ 0 ], 0.f, points[ i ][ 1 ] ); + } + glEnd(); + + // top face + glNormal3f( 0.f, 1.f, 0.f ); + glBegin( GL_POLYGON ); + for ( int i = 0 ; i < SAMPLE_COUNT; ++i ) { + glVertex3f( points[ i ][ 0 ], 1.f, points[ i ][ 1 ] ); + } + glEnd(); + // walls + glBegin( GL_TRIANGLE_STRIP ); + for ( int i = 0 ; i < SAMPLE_COUNT; ++i ) { + glNormal3f( points[ i ][ 0 ], 0.f, points[ i ][ 1 ] ); + glVertex3f( points[ i ][ 0 ], 1.f, points[ i ][ 1 ] ); + glVertex3f( points[ i ][ 0 ], 0.f, points[ i ][ 1 ] ); + } + glNormal3f( points[ 0 ][ 0 ], 0.f, points[ 0 ][ 1 ] ); + glVertex3f( points[ 0 ][ 0 ], 1.f, points[ 0 ][ 1 ] ); + glVertex3f( points[ 0 ][ 0 ], 0.f, points[ 0 ][ 1 ] ); + glEnd(); + + glEndList(); + } + + /////////////////////////////////////////////////////////////////////////// + + void Cylinder::init() { + if ( ! IS_REGISTERED ) { + GLContextManager::addCallback( &newGLContext ); + IS_REGISTERED = true; + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Cylinder::drawGL( bool select ) { + if ( _visible ) { + drawCylinder( _radius, _height, _r, _g, _b, 1.f, _style ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void Cylinder::drawCylinder( float radius, float height, float r, float g, float b, float a, GLenum style ) { + glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_POLYGON_BIT ); + // set up drawing + glDisable( GL_TEXTURE_2D ); + if ( a < 1.f ) { + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + glPolygonMode( GL_FRONT_AND_BACK, style ); + glColor4f(r,g,b,a); + glPushMatrix(); + glScalef( radius, height, radius ); + glCallList( GL_ID ); + glPopMatrix(); + glPopAttrib(); + } + + } // namespace SceneGraph +} // namespace Menge diff --git a/src/Menge/MengeCore/SceneGraph/shapes.h b/src/Menge/MengeCore/SceneGraph/shapes.h new file mode 100644 index 00000000..a6b32f88 --- /dev/null +++ b/src/Menge/MengeCore/SceneGraph/shapes.h @@ -0,0 +1,310 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file shapes.h + * @brief A library of simple renderable OpenGL shapes + */ + +#ifndef __SHAPES_H__ +#define __SHAPES_H__ + +// A collection of renderable shapes +#include "CoreConfig.h" +#include "Select.h" +#include "GLNode.h" + +#include "graphCommon.h" + +namespace Menge { + + namespace SceneGraph { + + /*! + * @brief Initializes the static functions for all shapes (as appropriate). + * + * When a new shape is created with a static "init" function, a call + * to an initialization function should be added into this function + * (defined in shapes.cpp). This allows for the drawing of shapes via + * static functions as well as by instances. + * + * It means the draw function doesn't have to test at each draw + * command if it has been properly initialized. + */ + MENGE_API void initShapes(); + + /*! + * @brief Emits OpenGL commands to create a sphere in OpenGL + * + * The sphere is constructed with N longitudinal and latitudinal points. The + * sphere has normals sufficient to support lighting. + * + * @param samples The number of longitudinal and latitudinal samples. + */ + MENGE_API void glSphere( int samples ); + + /*! + * @brief The basic shape class - a selectable GLNode. + */ + class MENGE_API Shape: public GLNode, public Selectable { + public: + /*! + * @brief Default constructor. + */ + Shape(): GLNode(), Selectable(), _r(1.f), _g(1.f), _b(1.f), _style(GL_FILL) {} + + /*! + * @brief Constructor with color and drawing style. + * + * @param r The red component of the shape's color (in the range [0, 1]). + * @param g The green component of the shape's color (in the range [0, 1]). + * @param b The blue component of the shape's color (in the range [0, 1]). + * @param s OpenGL render style: GL_FILL, GL_LINE, or GL_POINT. + */ + Shape( float r, float g, float b, GLenum s=GL_FILL ): GLNode(), Selectable(), _r(r), _g(g), _b(b), _style(s) {} + + /*! + * @brief Set the shape color from a vector. + * + * @param vec The rgb color, where each channel lies in the range [0, 1]. + */ + void setColor( const Vector3 & vec ) { _r=vec.x(); _g=vec.y(); _b=vec.z(); } + + /*! + * @brief Set the shape color from three separate values. + * + * @param r The red component of the shape's color (in the range [0, 1]). + * @param g The green component of the shape's color (in the range [0, 1]). + * @param b The blue component of the shape's color (in the range [0, 1]). + */ + void setColor( float r, float g, float b ) { _r=r; _g=g; _b=b; } + + /*! + * @brief Set the shape's render style. + * + * @param style The desired render style. Should be one of GL_FILL, GL_LINE, or GL_POINT. + */ + void setStyle( GLenum style ) { _style = style; } + + protected: + /*! + * @brief The red component of the shape's color. + */ + float _r; + + /*! + * @brief The green component of the shape's color. + */ + float _g; + + /*! + * @brief The blue component of the shape's color. + */ + float _b; + + /*! + * @brief The shape's OpenGL rendering style. Should be one of GL_FILL, GL_LINE, or GL_POINT. + */ + GLenum _style; + }; + + /*! + * @brief A GLNode for drawing circles. The circle is drawn around + * the world space origin, lying on the x-z plane. + */ + class MENGE_API Circle : public Shape { + public: + /*! + * @brief Default constructor. + */ + Circle():Shape(), _radius(1.f){} + + /*! + * @brief Constructor with color. + * + * @param r The red component of the circle's color (in the range [0, 1]). + * @param g The green component of the circle's color (in the range [0, 1]). + * @param b The blue component of the circle's color (in the range [0, 1]). + */ + Circle(float r, float g, float b):Shape(r,g,b), _radius(1.f) {} + + /*! + * @brief Function for drawing a circle into the context. + * + * The circle is drawn on the x-z OpenGL plane, centered on the origin. To change + * position or orientation, the draw call should be preceeded by appropriate transforms. + * + * @param select True if the circle is being drawn for selection purposes, + * false otherwise. + */ + void drawGL( bool select=false ); + + /*! + * @brief Static function for drawing circles in the context with out instances. + * + * The circle is drawn on the x-z OpenGL plane, centered on the origin. To change + * position or orientation, the draw call should be preceeded by appropriate transforms. + * + * @param radius The radius of the circle. + * @param r The red component of the shape's color (in the range [0, 1]). + * @param g The green component of the shape's color (in the range [0, 1]). + * @param b The blue component of the shape's color (in the range [0, 1]). + * @param a The alpha componet of the shape's color (in the range [0, 1]). + * @param style OpenGL render style: GL_FILL, GL_LINE, or GL_POINT. + */ + static void drawCircle( float radius, float r, float g, float b, float a, GLenum style=GL_FILL ); + + /*! + * @brief Simply draws the underlying primitive + */ + static void drawUnit(); + + /*! + * @brief Initializes the OpenGL primitives for drawing the circle. + * + * A call to this function has been added to initShapes. + */ + static void init(); + + protected: + /*! + * @brief The radius of the circle (in world space units). + */ + float _radius; + + /*! + * @brief Determines if the Circle::newGLContext has been registered. + */ + static bool IS_REGISTERED; + + /*! + * @brief The function to call when an OpenGL context has changed. + */ + static void newGLContext(); + + /*! + * @brief OpenGL display list for drawing a circle. + */ + static int GL_ID; + }; + + /*! + * @brief A GLNode for drawing cylinders. The cylinder has unit + * radius and unit height and the bottom of the cylinder + * sits on the origin. The height is along the y-axis. + */ + class MENGE_API Cylinder : public Shape { + public: + /*! + * @brief Default constructor. Unit size and default shape color + */ + Cylinder():Shape(), _radius(1.f), _height(1.f){} + + /*! + * @brief Size constructor. Sets the size of the cylinder to the + * specified radius and height and default shape color. + * @param radius The radius of the cylinder. + * @param height The height of the cylinder. + */ + Cylinder( float radius, float height ):Shape(), _radius(radius), _height(height){} + + /*! + * @brief Full constructor. Sets the size and color of the cylinder + * @param radius The radius of the cylinder. + * @param height The height of the cylinder. + * @param r The red component of the color (in the range [0,1] ). + * @param g The green component of the color (in the range [0,1] ). + * @param b The blue component of the color (in the range [0,1] ). + */ + Cylinder( float radius, float height, float r, float g, float b ):Shape(r,g,b), _radius(radius), _height(height){} + + /*! + * @brief The method for drawing the cylinder instance. + * @param select Determines if the cylinder is being drawn in selection mode. + */ + void drawGL( bool select=false ); + + /*! + * @brief Draw a cylinder without access to an instance + * + * @param radius The radius of the cylinder. + * @param height The height of the cylinder. + * @param r The red component of the color (in the range [0,1] ). + * @param g The green component of the color (in the range [0,1] ). + * @param b The blue component of the color (in the range [0,1] ). + * @param a The alpha component of the color (in the range [0,1] ). + * @param style The draw style of the shape - enumerations consistent with glPolygonMode are + * acceptable arguments. + */ + static void drawCylinder( float radius, float height, float r, float g, float b, float a, GLenum style=GL_FILL ); + + /*! + * @brief The initialization of the cylinder construction. + */ + static void init(); + + protected: + /*! + * @brief The radius of the cylinder. + */ + float _radius; + + /*! + * @brief The height of the cylinder. + */ + float _height; + + // This functionality works with the context manager + /*! + * @brief Reports if the class has been registered with the context manager + */ + static bool IS_REGISTERED; + + /*! + * @brief Called when the context changes. + */ + static void newGLContext(); + + /*! + * @brief The identifier for the display list for this primitive. + */ + static int GL_ID; + }; + } +} // namespace Menge +#endif // __SHAPES_H__ diff --git a/src/Menge/MengeCore/mengeCommon.h b/src/Menge/MengeCore/mengeCommon.h new file mode 100644 index 00000000..74556ee0 --- /dev/null +++ b/src/Menge/MengeCore/mengeCommon.h @@ -0,0 +1,71 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file common.h + * @brief A set of common includes for the core Menge library + */ + +#ifndef __MENGE_COMMON_H__ +#define __MENGE_COMMON_H__ + + +#ifdef _MSC_VER + // Visual Studio does not properly support exception specifciation + // i.e. void func() throw(x) + // This prevents it from spewing warnings. + #pragma warning( disable : 4290 ) +#endif + +// core configuration +#include "macros.h" +#include "CoreConfig.h" +#include "Logger.h" +#include "MengeException.h" + +// convenient STL functionality +#include +#include + +// math functionality +#include "Math/vector.h" +#include "Math/RandGenerator.h" +#include "Math/consts.h" +using namespace Menge::Math; + +#endif // __MENGE_COMMON_H__ diff --git a/src/Menge/MengeCore/resources/Funnel.cpp b/src/Menge/MengeCore/resources/Funnel.cpp new file mode 100644 index 00000000..3d0e9496 --- /dev/null +++ b/src/Menge/MengeCore/resources/Funnel.cpp @@ -0,0 +1,279 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Funnel.h" +#include "PortalPath.h" +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FunnelPlanner + ///////////////////////////////////////////////////////////////////// + + FunnelPlanner::FunnelPlanner() { + } + + ///////////////////////////////////////////////////////////////////// + + FunnelPlanner::~FunnelPlanner() { + } + + ///////////////////////////////////////////////////////////////////// + + void FunnelPlanner::computeCrossing( float radius, const Vector2 & startPos, PortalPath * path, size_t startPortal ) { + assert( path->getPortalCount() > 0 && "Funnel planner should only be applied to PortalPaths with at least one portal" ); + FunnelApex apex( startPortal - 1, startPos ); // if startPortal is zero, this should go to all 1s...i.e. -1 > all other size_t values + + const WayPortal * portal = path->getPortal( startPortal ); + Vector2 pLeft( portal->getLeft( radius ) ); + Vector2 pRight( portal->getRight( radius ) ); + Vector2 dirLeft( pLeft - apex._pos ); + Vector2 dirRight( pRight - apex._pos ); + #ifdef SIMPLE_FUNNEL + FunnelEdge funnelLeft( startPortal, dirLeft ); + FunnelEdge funnelRight( startPortal, dirRight ); + size_t currPortal = startPortal + 1; + const size_t PORTAL_COUNT = path->getPortalCount(); + while ( currPortal < PORTAL_COUNT ) { + portal = path->getPortal( currPortal ); + pLeft.set( portal->getLeft( radius ) ); + pRight.set( portal->getRight( radius ) ); + dirLeft.set( pLeft - apex._pos ); + dirRight.set( pRight - apex._pos ); + + // test left side of the funnel + if ( funnelRight.isOnRight( dirLeft ) ) { + // the portal's funnel is on the right of the current funnel + Vector2 oldApex = apex._pos; + Vector2 newApex = funnelRight._dir + apex._pos; + //if ( apex._id != -1 && apex._id < currPortal ) { + path->setWaypoints( apex._id + 1, funnelRight._id + 1, newApex, norm( funnelRight._dir ) ); + //} + apex.set( funnelRight._id, newApex ); + currPortal = funnelRight._id + 1; + + portal = path->getPortal( currPortal ); + pLeft.set( portal->getLeft( radius ) ); + pRight.set( portal->getRight( radius ) ); + dirLeft.set( pLeft - apex._pos ); + dirRight.set( pRight - apex._pos ); + funnelLeft.set( currPortal, dirLeft ); + funnelRight.set( currPortal, dirRight ); + ++currPortal; + + continue; + } else if ( funnelLeft.isOnRight( dirLeft ) ) { + funnelLeft.set( currPortal, dirLeft ); + } + + // test right side of the funnel + if ( funnelLeft.isOnLeft( dirRight ) ) { + // the portal's funnel is on the left of the current funnel + Vector2 oldApex = apex._pos; + Vector2 newApex = funnelLeft._dir + apex._pos; + //if ( apex._id != -1 && apex._id < currPortal ) { + path->setWaypoints( apex._id + 1, funnelLeft._id + 1, newApex, norm( funnelLeft._dir ) ); + //} + apex.set( funnelLeft._id, newApex ); + currPortal = funnelLeft._id + 1; + + portal = path->getPortal( currPortal ); + pLeft.set( portal->getLeft( radius ) ); + pRight.set( portal->getRight( radius ) ); + dirLeft.set( pLeft - apex._pos ); + dirRight.set( pRight - apex._pos ); + funnelLeft.set( currPortal, dirLeft ); + funnelRight.set( currPortal, dirRight ); + ++currPortal; + + continue; + } else if ( funnelRight.isOnLeft( dirRight ) ) { + funnelRight.set( currPortal, dirRight ); + } + ++currPortal; + } + + // Now handle goal + const Vector2 goalPt = path->getGoalCentroid(); + Vector2 goalDir( goalPt - apex._pos ); + + if ( funnelLeft.isOnLeft( goalDir ) ) { + // The goal point is on the left side of the funnel + if ( apex._id != -1 && apex._id < PORTAL_COUNT ) { + path->setWaypoints( apex._id + 1, PORTAL_COUNT, apex._pos + funnelLeft._dir, norm( funnelLeft._dir ) ); + } + } else if ( funnelRight.isOnRight( goalDir ) ) { + // The goal point is on the right side of the funnel + if ( apex._id != -1 && apex._id < PORTAL_COUNT ) { + path->setWaypoints( apex._id + 1, PORTAL_COUNT, apex._pos + funnelRight._dir, norm( funnelRight._dir ) ); + } + } + + if ( apex._id + 1 < PORTAL_COUNT ) { + path->setWaypoints( (size_t)apex._id + 1, (size_t)PORTAL_COUNT, goalPt, norm( goalPt - apex._pos ) ); + } + + #else + _left.push_back( FunnelEdge( startPortal - 1, startPortal, dirLeft, startPos ) ); + _right.push_back( FunnelEdge( startPortal - 1, startPortal, dirRight, startPos ) ); + const size_t PORTAL_COUNT = path->getPortalCount(); + for ( size_t i = startPortal + 1; i < PORTAL_COUNT; ++i ) { + portal = path->getPortal( i ); + + // investigate the left point + pLeft.set( portal->getLeft( radius ) ); + bool apexMoved = false; + while ( !_right.empty() ) { + std::list< FunnelEdge >::iterator itr = _right.begin(); + Vector2 dir = pLeft - itr->_origin; + if ( itr->isOnRight( dir ) ) { + apexMoved = true; + Vector2 newApex = itr->_origin + itr->_dir; + path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) ); + apex.set( itr->_endID, newApex ); + _right.pop_front(); + } else { + break; + } + } + if ( apexMoved ) { + _left.clear(); + _left.push_back( FunnelEdge( apex._id, i, pLeft - apex._pos, apex._pos ) ); + } else { + std::list< FunnelEdge >::reverse_iterator itr = _left.rbegin(); + while ( ! _left.empty() ) { + Vector2 dir = pLeft - itr->_origin; + if ( itr->isOnRight( dir ) ) { + _left.pop_back(); + itr = _left.rbegin(); + } else { + break; + } + } + if ( _left.empty() ) { + _left.push_back( FunnelEdge( apex._id, i, pLeft - apex._pos, apex._pos ) ); + } else { + Vector2 origin( itr->_origin + itr->_dir ); + _left.push_back( FunnelEdge( itr->_endID, i, pLeft - origin, origin ) ); + } + } + + // investigate the right point + pRight.set( portal->getRight( radius ) ); + apexMoved = false; + while ( !_left.empty() ) { + std::list< FunnelEdge >::iterator itr = _left.begin(); + Vector2 dir = pRight - itr->_origin; + if ( itr->isOnLeft( dir ) ) { + apexMoved = true; + Vector2 newApex = itr->_origin + itr->_dir; + path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) ); + apex.set( itr->_endID, newApex ); + _left.pop_front(); + } else { + break; + } + } + if ( apexMoved ) { + _right.clear(); + _right.push_back( FunnelEdge( apex._id, i, pRight - apex._pos, apex._pos ) ); + } else { + std::list< FunnelEdge >::reverse_iterator itr = _right.rbegin(); + while ( ! _right.empty() ) { + Vector2 dir = pRight - itr->_origin; + if ( itr->isOnLeft( dir ) ) { + _right.pop_back(); + itr = _right.rbegin(); + } else { + break; + } + } + if ( _right.empty() ) { + _right.push_back( FunnelEdge( apex._id, i, pRight - apex._pos, apex._pos ) ); + } else { + Vector2 origin( itr->_origin + itr->_dir ); + _right.push_back( FunnelEdge( itr->_endID, i, pRight - origin, origin ) ); + } + } + } + // handle the goal + const Vector2 goalPt = path->getGoalCentroid(); + Vector2 goalDir; + + bool apexMoved = false; + while ( !_left.empty() ) { + std::list< FunnelEdge >::iterator itr = _left.begin(); + goalDir.set( goalPt - itr->_origin ); + if ( itr->isOnLeft( goalDir ) ) { + apexMoved = true; + Vector2 newApex = itr->_origin + itr->_dir; + apex.set( itr->_endID, newApex ); + path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) ); + _left.pop_front(); + } else { + break; + } + } + if ( apexMoved ) { + goalDir.set( goalPt - apex._pos ); + path->setWaypoints( apex._id + 1, PORTAL_COUNT, goalPt, norm( goalDir ) ); + } else { + // apexMoved is already false -- it is the only way to reach this branch + while ( !_right.empty() ) { + std::list< FunnelEdge >::iterator itr = _right.begin(); + goalDir.set( goalPt - itr->_origin ); + if ( itr->isOnRight( goalDir ) ) { + apexMoved = true; + Vector2 newApex = itr->_origin + itr->_dir; + apex.set( itr->_endID, newApex ); + path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) ); + _right.pop_front(); + } else { + break; + } + } + + goalDir.set( goalPt - apex._pos ); + path->setWaypoints( apex._id + 1, PORTAL_COUNT, goalPt, norm( goalDir ) ); + + } + #endif // SIMPLE_FUNNEL + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/Funnel.h b/src/Menge/MengeCore/resources/Funnel.h new file mode 100644 index 00000000..7b02a509 --- /dev/null +++ b/src/Menge/MengeCore/resources/Funnel.h @@ -0,0 +1,238 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __FUNNEL_H__ +#define __FUNNEL_H__ + +/*! + * @file Funnel.h + * @brief The various classes for performing funnel algorithm on a portal path. + * The funnel algorithm is from: Lee and Preparata 1984 + * "Euclidean Shortest Paths in the Presence of Rectilinear Barriers" + */ + +#include "mengeCommon.h" +#include + +namespace Menge { + + /*! + * @brief Determines if it uses simple funnel algorithm (no deque, just restart) + * or complex (using deque) + */ + // TODO: Determine which is faster. + //#define SIMPLE_FUNNEL + + // FORWARD DECLARATION + class PortalPath; + class FunnelPlanner; + + /*! + * @brief The apex of the funnel. + */ + class FunnelApex { + public: + /*! + * @brief Constructor + * + * @param id The index of the portal associated with this + * apex. If -1, it is the start position. + * @param point The location of the start point. + */ + FunnelApex( size_t id, const Vector2 & point ): _id(id), _pos(point) {} + + /*! + * @brief Sets the values of the apex + * + * @param id The index of the portal associated with this + * apex. If -1, it is the start position. + * @param point The location of the start point. + */ + inline void set( size_t id, const Vector2 & point ) { _id = id; _pos.set(point); } + + friend class FunnelPlanner; + protected: + /*! + * @brief The identifier associated with this apex point. + * if -1, it is the start position, otherwise, a point + * extracted from the portal with the given id. + */ + size_t _id; + + /*! + * @brief The position of the apex. + */ + Vector2 _pos; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The edge of a funnel. + */ + class FunnelEdge { + public: + /*! + * @brief Default constructor. No initialization. + */ + FunnelEdge(){} + + #ifdef SIMPLE_FUNNEL + /*! + * @brief Constructor. + * + * @param id The identifier of the portal from which this + * direction arises. + * @param dir The direction from the apex to the portal. + */ + FunnelEdge( size_t id, const Vector2 & dir ):_id(id), _dir(dir) {} + #else + /*! + * @brief Constructor. + * + * @param id The identifier of the portal from which this + * direction arises. + * @param end The identifier of the portal at which this + * wedge ends. + * @param dir The direction from the apex to the portal. + * @param origin The origin of this funnel "wedge". + */ + FunnelEdge( size_t id, size_t end, const Vector2 & dir, const Vector2 & origin ):_id(id), _endID(end), _dir(dir), _origin(origin) {} + #endif + + /*! + * @brief Reports if the given direction is to the left of this edge. + * + * @param dir The direction to test. + * @returns A boolean reporting if the direction is to the left of this + * edge (true) or to the right (false). + */ + inline bool isOnLeft( const Vector2 & dir ) const { return det( _dir, dir ) > EPS; } + + /*! + * @brief Reports if the given direction is to the right of this edge. + * + * @param dir The direction to test. + * @returns A boolean reporting if the direction is to the right of this + * edge (true) or to the left (false). + */ + inline bool isOnRight( const Vector2 & dir ) const { return det( dir, _dir ) > EPS; } + + /*! + * @brief Sets the properties of the funnel edge. + * + * @param id The id of the portal to which this funnel edge is associated. + * @param dir The direction of the edge. + */ + inline void set( size_t id, const Vector2 & dir ) { _id = id; _dir.set( dir ); } + + friend class FunnelPlanner; + + protected: + #ifdef SIMPLE_FUNNEL + /*! + * @brief The identifier of the portal for this direction + */ + size_t _id; + + #else + /*! + * @brief The identifier of the portal from which this wedge originates. + */ + size_t _id; + /*! + * @brief The identifier of the portal that ENDS the wedge. + */ + size_t _endID; + + /*! + * @brief The origin of the wedge + */ + Vector2 _origin; + #endif + + /*! + * @brief The direction of this funnel edge + */ + Vector2 _dir; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief The class that implements the funnel algorithm. + */ + class FunnelPlanner { + public: + /*! + * @brief Constructor + */ + FunnelPlanner(); + + /*! + * @brief Destructor + */ + ~FunnelPlanner(); + + /*! + * @brief Computes the crossings for the given path based on + * the funnel algorithm. + * + * @param radius The radius of the agent. + * @param startPos The starting position of the path. + * @param path A pointer to a portal path. + * @param startPortal The portal in the path to start wtih + */ + void computeCrossing( float radius, const Vector2 & startPos, PortalPath * path, size_t startPortal=0 ); + + #ifndef SIMPLE_FUNNEL + protected: + /*! + * @brief The queue for the left side of the funnel. + */ + std::list< FunnelEdge > _left; + + /*! + * @brief The queue for the right side of the funnel. + */ + std::list< FunnelEdge > _right; + #endif // SIMPLE_FUNNEL + }; +} // namespace Menge + +#endif // __FUNNEL_H__ diff --git a/src/Menge/MengeCore/resources/Graph.cpp b/src/Menge/MengeCore/resources/Graph.cpp new file mode 100644 index 00000000..4ab9969c --- /dev/null +++ b/src/Menge/MengeCore/resources/Graph.cpp @@ -0,0 +1,320 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Graph.h" +#include "GraphEdge.h" +#include "RoadMapPath.h" +#include "MinHeap.h" +#include "Core.h" +#include "BaseAgent.h" +#include "SpatialQueries/SpatialQuery.h" +#include "Goals/Goal.h" +#include +#include +#include + +#ifdef _OPENMP +#include +#endif + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Graph + ///////////////////////////////////////////////////////////////////// + + const std::string Graph::LABEL("graph"); + + ///////////////////////////////////////////////////////////////////// + + Graph::Graph( const std::string & fileName ): Resource(fileName), _vCount(0), _vertices(0x0), DATA_SIZE(0), STATE_SIZE(0), _HEAP(0x0), _DATA(0x0), _STATE(0x0) { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + Graph::~Graph() { + clear(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void Graph::clear() { + if ( _vCount ) { + _vCount = 0; + delete [] _vertices; + _vertices = 0x0; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + Resource * Graph::load( const std::string & fileName ) { + std::ifstream f; + f.open( fileName.c_str(), std::ios::in ); + + if ( !f.is_open() ) { + logger << Logger::ERR_MSG << "Error opening the roadmap file: " << fileName << "\n"; + return 0x0; + } + + Graph * graph = new Graph( fileName ); + + // load vertices + if ( ! ( f >> graph->_vCount ) ) { + logger << Logger::ERR_MSG << "Error parsing roadmap: file didn't start with an int (vertex count).\n"; + graph->destroy(); + return 0x0; + } + graph->_vertices = new GraphVertex[ graph->_vCount ]; + size_t * vertNbr = new size_t[ graph->_vCount ]; + int degree; + float x, y; + for ( size_t i = 0; i < graph->_vCount; ++i ) { + if ( ! ( f >> degree >> x >> y ) ) { + logger << Logger::ERR_MSG << "Error parsing roadmap: format error for vertex " << (i + 1) << ".\n"; + graph->destroy(); + delete [] vertNbr; + return 0x0; + } + graph->_vertices[ i ].setID( i ); + graph->_vertices[ i ].setPosition( Vector2( x, y ) ); + graph->_vertices[ i ].setDegree( degree ); + vertNbr[ i ] = 0; + } + + // load edges + size_t eCount; + if ( ! ( f >> eCount ) ) { + logger << Logger::ERR_MSG << "Error parsing roadmap: didn't find edge count when expected.\n"; + delete [] vertNbr; + graph->destroy(); + return 0x0; + } + + for ( size_t e = 0; e < eCount; ++ e ) { + GraphEdge edge; + int from, to; + if ( ! ( f >> from >> to ) ) { + logger << Logger::ERR_MSG << "Error parsing roadmap: format error for edge " << ( e + 1 ) << ".\n"; + delete [] vertNbr; + graph->destroy(); + return false; + } + edge.setDistance( graph->_vertices[ from ].getDistance( graph->_vertices[ to ] ) ); + edge.setNeighbor( &graph->_vertices[ to ] ); + graph->_vertices[ from ].setEdge( edge, vertNbr[ from ] ); + ++vertNbr[ from ]; + edge.setNeighbor( &graph->_vertices[ from ] ); + graph->_vertices[ to ].setEdge( edge, vertNbr[ to ] ); + ++vertNbr[ to ]; + } + + graph->initHeapMemory(); + return graph; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + RoadMapPath * Graph::getPath( const Agents::BaseAgent * agent, const BFSM::Goal * goal ) { + // Find the closest visible node to agent position + size_t startID = getClosestVertex( agent->_pos, agent->_radius ); + // Find the closest visible node to goal position + Vector2 goalPos = goal->getCentroid(); + size_t endID = getClosestVertex( goalPos, agent->_radius ); + // Compute the path based on those nodes + RoadMapPath * path = getPath( startID, endID ); + if ( path ) { + path->setGoalPos( goal ); + } + return path; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const GraphVertex * Graph::getVertex( size_t i ) const { + assert( i < _vCount && "Indexing invalid graph vertex" ); + return &_vertices[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + size_t Graph::getClosestVertex( const Vector2 & point, float radius ) { + assert( _vCount > 0 && "Trying to operate on an empty roadmap" ); + // TODO: Make this faster + + float bestDistSq = INFTY; + size_t bestID = -1; + for ( size_t i = 0; i < _vCount; ++i ) { + float testDistSq = absSq( _vertices[i].getPosition() - point ); + if ( testDistSq < bestDistSq ) { + if ( Menge::SPATIAL_QUERY->queryVisibility( point, _vertices[i].getPosition(), radius ) ) { + bestDistSq = testDistSq; + bestID = i; + } + } + } + + assert( bestID != -1 && "Roadmap Graph was unable to find a visible vertex" ); + + return bestID; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + RoadMapPath * Graph::getPath( size_t startID, size_t endID ) { + const size_t N = _vCount; + #ifdef _OPENMP + // Assuming that threadNum \in [0, omp_get_max_threads() ) + const unsigned int threadNum = omp_get_thread_num(); + AStarMinHeap heap( _HEAP + threadNum * N, _DATA + threadNum * DATA_SIZE, _STATE + threadNum * STATE_SIZE, _PATH + threadNum * N, N ); + #else + AStarMinHeap heap( _HEAP, _DATA, _STATE, _PATH, N ); + #endif + + const Vector2 goalPos( _vertices[ endID ].getPosition() ); + + heap.g( (unsigned int)startID, 0 ); + heap.h( (unsigned int)startID, computeH( startID, goalPos ) ); + heap.f( (unsigned int)startID, heap.h( (unsigned int)startID ) ); + heap.push( (unsigned int)startID ); + + bool found = false; + while ( !heap.empty() ) { + unsigned int x = heap.pop(); + + if ( x == endID ) { + found = true; + break; + } + + GraphVertex & vert = _vertices[ x ]; + + const size_t E_COUNT = vert.getEdgeCount(); + for ( size_t n = 0; n < E_COUNT; ++n ) { + const GraphVertex * nbr = vert.getNeighbor( n ); + size_t y = nbr->getID(); + if ( heap.isVisited( (unsigned int)y ) ) continue; + float distance = vert.getDistance( n ); + float tempG = heap.g( x ) + distance; + + bool inHeap = heap.isInHeap( (unsigned int)y ); + if ( ! inHeap ) { + heap.h( (unsigned int)y, computeH( y, goalPos ) ); + } + if ( tempG < heap.g( (unsigned int)y ) ) { + heap.setReachedFrom( (unsigned int)y, (unsigned int)x ); + heap.g( (unsigned int)y, tempG ); + heap.f( (unsigned int)y, tempG + heap.h( (unsigned int)y ) ); + } + if ( ! inHeap ) { + heap.push( (unsigned int)y ); + } + } + } + if ( !found ) { + logger << Logger::ERR_MSG << "Was unable to find a path from " << startID << " to " << endID << "\n"; + return 0x0; + } + + // Count the number of nodes in the path + size_t wayCount = 1; // for the startID + size_t next = endID; + while ( next != startID ) { + ++wayCount; + next = heap.getReachedFrom( (unsigned int)next ); + } + + RoadMapPath * path = new RoadMapPath( wayCount ); + next = endID; + for ( size_t i = wayCount; i > 0; --i ) { + path->setWayPoint( i - 1, _vertices[ next ].getPosition() ); + next = heap.getReachedFrom( (unsigned int)next ); + } + + return path; + } + + ///////////////////////////////////////////////////////////////////// + + void Graph::initHeapMemory() { + int threadCount = 1; + #ifdef _OPENMP + logger << Logger::INFO_MSG << "OMP ENABLED!\n"; + threadCount = omp_get_max_threads(); + #endif + logger << Logger::INFO_MSG << "Caching roadmap A* data for " << threadCount << " threads\n"; + if ( _DATA ) { + delete [] _DATA; + _DATA = 0x0; + delete [] _STATE; + _STATE = 0x0; + delete [] _HEAP; + _HEAP = 0x0; + delete [] _PATH; + _PATH = 0x0; + } + + DATA_SIZE = 3 * _vCount; // the number of floats per thread in _data + STATE_SIZE = 2 * _vCount; // the number of bools, per thread, in _state; + if ( _vCount ) { + _DATA = new float[ threadCount * DATA_SIZE ]; + _STATE = new bool[ threadCount * STATE_SIZE ]; + _HEAP = new unsigned int[ threadCount * _vCount ]; + _PATH = new unsigned int[ threadCount * _vCount ]; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + GraphPtr loadGraph( const std::string & fileName ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &Graph::load, Graph::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No resource available\n"; + throw ResourceException(); + } + Graph * graph = dynamic_cast< Graph * >( rsrc ); + if ( graph == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a Graph\n"; + throw ResourceException(); + } + return GraphPtr( graph ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/Graph.h b/src/Menge/MengeCore/resources/Graph.h new file mode 100644 index 00000000..8350f7fb --- /dev/null +++ b/src/Menge/MengeCore/resources/Graph.h @@ -0,0 +1,256 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Graph.h + * @brief The definition of a graph for performing graph searches + * and path planning. + */ + +#ifndef __GRAPH_H__ +#define __GRAPH_H__ + +#include "mengeCommon.h" +#include "Resource.h" +#include "GraphVertex.h" + +namespace Menge { + + // Forward declarations + class GraphEdge; + class RoadMapPath; + namespace BFSM { + class Goal; + } + + namespace Agents { + class BaseAgent; + } + + /*! + * @brief A roadmap graph and the infrastructure for performing graph + * searches. NOTE: This implementation assumes that the graph + * doesn't change. + */ + class MENGE_API Graph : public Resource { + public: + /*! + * @brief Constructor. + * + * @param fileName The name of the file which contains the vector field definition. + */ + Graph( const std::string & fileName ); + + protected: + /*! + * @brief Destructor. + */ + ~Graph(); + + public: + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const { return LABEL; } + + /*! + * @brief Clears the graph -- such that it has no vertices and no edges. + */ + void clear(); + + /*! + * @brief Parses a graph definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a Graph, but to a Resource. The ResourceManager + * uses it to load and instantiate Graph instances. + * + * @param fileName The path to the file containing the VectorField + * definition. + * @returns A pointer to the new Graph (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief Compute path + * + * @param agent The agent for whom to compute the path. + * @param goal The agent's goal. + * @returns A pointer to a RoadMapPath. If there is an error, + * the poitner will be NULL. + */ + RoadMapPath * getPath( const Agents::BaseAgent * agent, const BFSM::Goal * goal ); + + /*! + * @brief Return the number of vertices in the graph. + * + * @returns The number of vertices in the graph. + */ + inline size_t getVertexCount() const { return _vCount; } + + /*! + * @brief Returns a const pointer to the ith vertex. + * + * The validitiy of the index is only checked in debug mode with + * an assertion. + * + * @param i The index of the desired pointer. + * @returns A const pointer to the ith graph vertex. + */ + const GraphVertex * getVertex( size_t i ) const; + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + protected: + + /*! + * @brief Find the closest visible graph vertex to the given + * point. + * + * @param point The point to connect to the graph. + * @param radius The radius of the agent testing. + * @returns The index of the closest node. + */ + size_t getClosestVertex( const Vector2 & point, float radius ); + + /*! + * @brief Computes the shortest path from start to end vertices. + * + * This function instantiates a new path, but the caller is responsible + * for deleting it. + * + * @param startID The index of the start vertex. + * @param endID The index of the end vertex. + * @returns A pointer to a new RoadMapPath. + */ + RoadMapPath * getPath( size_t startID, size_t endID ); + + /*! + * @brief Compute's "h" for the A* algorithm. H is the estimate of the + * cost of a node to a goal point. In this case, simply Euclidian + * distance. + * + * @param v The vertex to estimate the cost. + * @param goal The goal point. + * @returns The h-value. + */ + inline float computeH( size_t v, const Vector2 & goal ) { return abs( _vertices[v].getPosition() - goal ); } + + /*! + * @brief The number of vertices. + */ + size_t _vCount; + + /*! + * @brief An array containing all vertices. + */ + GraphVertex * _vertices; + + /*! + * @brief Initializes the heap memory based on current + * graph state. + */ + void initHeapMemory(); + + /*! + * @brief The size of a block of data used for COST in + * the A* algorithm (3N, N = number of nodes) + */ + size_t DATA_SIZE; + + /*! + * @brief The size of a block of data used for STATE in + * the A* algorithm (2N, N = number of nodes) + */ + size_t STATE_SIZE; + + /*! + * @brief The full set of data to serve as the heap + * There are N entries in a single heap + * and one heap per thread. + */ + unsigned int * _HEAP; + + /*! + * @brief The full set of data for reconstructing the path. + * For any given entry i, the value at i is the index of + * the node from which i was reached. There is one block + * per thread. + */ + unsigned int * _PATH; + + /*! + * @brief The block of data for tracking the f, g, and h data for nodes. + * (This is where DATA_SIZE = 3N comes from.) One block for + * each active thread. + * The first N values in a block are the f values, the next N are the g values, + * and the last set of N values are the h values. + */ + float * _DATA; + + /*! + * @brief Block of data for reportin node state (if its in a heap or if its + * no longer used for calculation. First N booleans are "in heap", second + * N are "finished". One block of 2N booleans per thread. + */ + bool * _STATE; + }; + + /*! + * @brief The definition of the managed pointer for Graph data + */ + typedef ResourcePtr< Graph > GraphPtr; + + /*! + * @brief Loads the graph of the given name + * + * @param fileName The name of the file containing the graph definition. + * @returns The GraphPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ + GraphPtr loadGraph( const std::string & fileName ) throw ( ResourceException ); +} // namespace Menge + +#endif // __GRAPH_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/GraphEdge.cpp b/src/Menge/MengeCore/resources/GraphEdge.cpp new file mode 100644 index 00000000..8c4ef688 --- /dev/null +++ b/src/Menge/MengeCore/resources/GraphEdge.cpp @@ -0,0 +1,55 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GraphEdge.h" +#include "GraphVertex.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of GraphEdge + ///////////////////////////////////////////////////////////////////// + + GraphEdge::GraphEdge():_distance(0.f), _nbr(0x0) { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + GraphEdge::~GraphEdge() { + } +} // namespace Menge diff --git a/src/Menge/MengeCore/resources/GraphEdge.h b/src/Menge/MengeCore/resources/GraphEdge.h new file mode 100644 index 00000000..a422d5f9 --- /dev/null +++ b/src/Menge/MengeCore/resources/GraphEdge.h @@ -0,0 +1,112 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GraphEdge.h + * @brief The definition of a graph edge for performing graph searches + * and path planning. + */ + +#ifndef __GRAPH_EDGE_H__ +#define __GRAPH_EDGE_H__ + +#include "mengeCommon.h" + +namespace Menge { + + // forward declaration + class GraphVertex; + + /*! + * @brief A graph edge. + */ + class GraphEdge { + public: + /*! + * @brief Constructor. + */ + GraphEdge(); + + /*! + * @brief Destructor + */ + ~GraphEdge(); + + /*! + * @brief Set's the neighboring vertex + * + * @param v The first connected vertex. + */ + void setNeighbor( GraphVertex * v ) { _nbr = v; } + + /*! + * @brief Sets the distance between the vertices + * + * @param d The distance between the two vertices. + */ + void setDistance( float d ) { _distance = d; } + + /*! + * @brief Reports the distance between the vertices connected + * by this edge. + * + * @returns The length of this edge. + */ + inline float getDistance() const { return _distance; } + + /*! + * @brief Returns the first attached GraphVertex + * + * @returns A pointer to the first graph vertex. + */ + GraphVertex * getNeighbor() const { return _nbr; } + + protected: + /*! + * @brief The distance between the two vertices connected by this edge. + */ + float _distance; + + /*! + * @brief A pointer to the first graph vertex connected by + * this edge. + */ + GraphVertex * _nbr; + }; +} // namespace Menge +#endif // __GRAPH_EDGE_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/GraphVertex.cpp b/src/Menge/MengeCore/resources/GraphVertex.cpp new file mode 100644 index 00000000..331407df --- /dev/null +++ b/src/Menge/MengeCore/resources/GraphVertex.cpp @@ -0,0 +1,110 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "GraphVertex.h" +#include "GraphEdge.h" +#include + +namespace Menge { + + ////////////////////////////////////////////////////////////////////////////////////// + // Implementation of GraphVertex + ////////////////////////////////////////////////////////////////////////////////////// + + GraphVertex::GraphVertex(): _edges(0x0), _edgeCount(0), _pos(), _id(-1) { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + GraphVertex::~GraphVertex() { + if ( _edges ) { + delete [] _edges; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + GraphVertex & GraphVertex::operator=( const GraphVertex & v ) { + // Copy edges + // If I already have memory and it is too small, delete and create + if ( _edgeCount < v._edgeCount ) { + if ( _edgeCount > 0 ) delete [] _edges; + _edges = new GraphEdge[ v._edgeCount ]; + } + + _edgeCount = v._edgeCount; + for ( unsigned int e = 0; e < _edgeCount; ++e ) { + _edges[e] = v._edges[e]; + } + + _pos = v._pos; + _id = v._id; + return *this; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float GraphVertex::getDistance( size_t i ) const { + assert( i < _edgeCount && "Trying to get distance to a neighbor with an invalid index." ); + return _edges[ i ].getDistance(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void GraphVertex::setEdge( const GraphEdge & edge, size_t i ) { + assert( i < _edgeCount && "Trying to set a neighbor with an invalid index" ); + _edges[ i ] = edge; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const GraphVertex * GraphVertex::getNeighbor( size_t i ) const { + assert( i < _edgeCount && "Trying to access a neighbor with an invalid index" ); + return _edges[ i ].getNeighbor(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void GraphVertex::setDegree( size_t degree ) { + if ( _edgeCount ) { + delete [] _edges; + } + _edgeCount = degree; + if ( _edgeCount ) _edges = new GraphEdge[ _edgeCount ]; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/GraphVertex.h b/src/Menge/MengeCore/resources/GraphVertex.h new file mode 100644 index 00000000..936299b2 --- /dev/null +++ b/src/Menge/MengeCore/resources/GraphVertex.h @@ -0,0 +1,197 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GraphVertex.h + * @brief The definition of a graph vertex for performing graph searches + * and path planning. + */ + +#ifndef __GRAPH_VERTEX_H__ +#define __GRAPH_VERTEX_H__ + +#include "mengeCommon.h" +#include "GraphEdge.h" + +namespace Menge { + + /*! + * @brief A graph vertex. + */ + class GraphVertex { + public: + /*! + * @brief Constructor + */ + GraphVertex(); + + /*! + * @brief Destructor + */ + ~GraphVertex(); + + /*! + * @brief Assignment operator + */ + GraphVertex & operator=( const GraphVertex & n ); + + /*! + * @brief Computes the distance between this vertex and the + * given vertex. + * + * @param other The other vertex. + * @returns The Euclidian distance between this vertex and the + * other vertex. + */ + float getDistance( const GraphVertex & other ) { return abs( _pos - other._pos ); } + + /*! + * @brief Reports the distance to the ith neighbor. + * + * @param i The index of the desired neighbor. + * @returns The distance to the ith neghbor. + */ + float getDistance( size_t i ) const; + + /*! + * @brief Sets the node identifier. + * + * @param id The identifier to set this node to. + */ + void setID( size_t id ) { _id = id; } + + /*! + * @brief Retrive the identifier for this node. + */ + size_t getID() const { return _id; } + + /*! + * @brief Sets the graph vertex's position. + * + * @param p The point value to set. + */ + inline void setPosition( const Vector2 & p ) { _pos.set( p ); } + + /*! + * @brief Reports the position of the vertex. + * + * @returns The position of the vertex. + */ + Vector2 getPosition() const { return _pos; } + + /*! + * @brief Sets the ith edge for the vertex. + * + * @param edge The edge to set + * @param i The index to set. + */ + void setEdge( const GraphEdge & edge, size_t i ); + + /*! + * @brief Reports the number of vertices adjacent to this vertex. + */ + size_t getNeighborCount() const { return _edgeCount; } + + /*! + * @brief Returns a pointer to the ith neighbor. + * + * @param i The index of the neighboring vertex to retrieve. + * The index is defined in the range [0, N-1], where + * this vertex has N neighbors. + * @returns A pointer to the ith neighboring vertex. + */ + const GraphVertex * getNeighbor( size_t i ) const; + + /*! + * @brief Sets the degree -- the number of neighbors this vertex + * has + * + * @param degree The number of neighbors this vertex has. + */ + void setDegree( size_t degree ); + + /*! + * @brief Reports the number of edges on the node. + * + * @returns The number of edges. + */ + size_t getEdgeCount() const { return _edgeCount; } + + /*! + * @brief Retrieves the ith edge connected to this node. + * + * @param i The local index of the desired edge. + * @returns A pointer to the ith edge. + */ + GraphEdge & getEdge( size_t i ) { return _edges[ i ]; } + + /*! + * @brief Retrieves a const pointer to the ith edge connected to this node. + * + * @param i The local index of the desired edge. + * @returns A pointer to the ith edge. + */ + const GraphEdge & getEdge( size_t i ) const { return _edges[ i ]; } + + protected: + + /*! + * @brief An array of edges connecting to other vertices + */ + GraphEdge * _edges; + + /*! + * @brief The number of edges connecting to this vertex. + */ + size_t _edgeCount; + + /*! + * @brief The position of this vertex. + */ + Vector2 _pos; + + /*! + * @brief The identifier for this vertex. + */ + size_t _id; + }; + +} // namespace Menge +#endif // __GRAPH_VERTEX_H__ + + \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/MinHeap.cpp b/src/Menge/MengeCore/resources/MinHeap.cpp new file mode 100644 index 00000000..d2740cc3 --- /dev/null +++ b/src/Menge/MengeCore/resources/MinHeap.cpp @@ -0,0 +1,128 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "MinHeap.h" +#include +#ifndef _MSC_VER +#include +#endif + +namespace Menge { + + ////////////////////////////////////////////////////////////////////////////////////// + // Implementation of MinHeap + ////////////////////////////////////////////////////////////////////////////////////// + + AStarMinHeap::AStarMinHeap( unsigned int * heap, float * data, bool * state, unsigned int * path, size_t N ) { + _f = data; + _g = _f + N; + _h = _g + N; + _inHeap = state; + _visited = _inHeap + N; + _heap = heap; + _cameFrom = path; + initialize( N ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void AStarMinHeap::initialize( size_t N ) { + // This code assumes that the f-value is the first block of the data + // and _inHeap is the first block of the state + // TODO: Is it stritly necessary to initialize the values as a block? + // Can't they be implictly initialized by the value of _minIndex + memset( _f, 0x7f, sizeof( float ) * 3 * N ); + memset( _inHeap, 0x0, sizeof( bool ) * 2 * N ); + // note: don't need to initialize the heap array + _minIdx = _nextFree = 0; + _minKey = 0.f; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + unsigned int AStarMinHeap::pop() { + unsigned int returnVal = _heap[ _minIdx ]; + _inHeap[ returnVal ] = false; + _visited[ returnVal ] = true; + // Swap into this slot as necessary + --_nextFree; + if ( _minIdx != _nextFree ) { + _heap[ _minIdx ] = _heap[ _nextFree ]; + } + // Identify the new minimum + _minIdx = 0; + _minKey = _f[_heap[0]]; + for ( unsigned int i = 1; i < _nextFree; ++i ) { + const unsigned int x = _heap[i]; + if ( _f[ x ] < _minKey ) { + _minIdx = i; + _minKey = _f[ x ]; + } + } + return returnVal; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void AStarMinHeap::push( unsigned int x ) { + if ( _f[ x ] < _minKey ) { + _minIdx = _nextFree; + _minKey = _f[ x ]; + } + _inHeap[ x ] = true; + _heap[ _nextFree ] = x; + ++_nextFree; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void AStarMinHeap::changeF( unsigned int val, float key ) { + // Only has an impact if this introduces a new minimum + if ( key < _minKey ) { + _minKey = key; + for ( unsigned int i = 0; i < _nextFree; ++i ) { + if ( _heap[ i ] == val ) { + _minIdx = i; + break; + } + } + } + _f[ val ] = key; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/MinHeap.h b/src/Menge/MengeCore/resources/MinHeap.h new file mode 100644 index 00000000..76197416 --- /dev/null +++ b/src/Menge/MengeCore/resources/MinHeap.h @@ -0,0 +1,258 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file MinHeap.h + * @brief Special MinHeap implementaiton which will work with + * the A* algorithm and, particulary, is threadsafe. + */ + +#ifndef __MIN_HEAP_H__ +#define __MIN_HEAP_H__ + +#ifndef _WIN32 +#include "sys/types.h" +#endif + +namespace Menge { + + /*! + * @brief An implementation of a min heap for A* algorithm. + * The heap needs to be able to restructure itself because + * the values of nodes IN the heap can change due to + * the A* algorithm. + * + * Also tracks all of the A* data. + */ + class AStarMinHeap { + public: + /*! + * @brief Constructor. + * + * @param heap A pointer to a block of memory to be used for the heap + * for N nav mesh nodes. + * @param data A pointer to a block of memory to be used for the A* data + * (f, g, & h) for N nav mesh nodes. + * @param state A pointer to a block of memory to be used for the heap state + * (in heap & finished) for N nav mesh nodes. + * @param path A pointer to a block of memory to be used for recording the + * path taken. + * @param N The number of nodes. + */ + AStarMinHeap( unsigned int * heap, float * data, bool * state, unsigned int * path, size_t N ); + + /*! + * @brief Reports if the heap is empty. + * + * @returns True if the heap is empty, false if it is not. + */ + bool empty() const { return _nextFree == 0; } + + /*! + * @brief Extract the minimum keyed value. + * + * @returns The index of the nav mesh node with the minimum keyed value. + */ + unsigned int pop(); + + /*! + * @brief Insert a new value into the heap. + * + * @param x The index of the node to insert. + */ + void push( unsigned int x ); + + /*! + * @brief Set the g-value for the given node. + * + * @param node The nav mesh node index for which the g-value is to be set. + * @param value The g-value for the given node. + */ + inline void g( unsigned int node, float value ) { _g[ node ] = value; } + + /*! + * @brief Retrieve the g-value for the given node. + * + * @param node The nav mesh node index whose g-value is to be retrieved. + * @returns The g-value of the indexed node. + */ + inline float g( unsigned int node ) const { return _g[ node ]; } + + /*! + * @brief Set the h-value for the given node. + * + * @param node The nav mesh node index for which the h-value is to be set. + * @param value The h-value for the given node. + */ + inline void h( unsigned int node, float value ) { _h[ node ] = value; } + + /*! + * @brief Retrieve the h-value for the given node. + * + * @param node The nav mesh node index whose h-value is to be retrieved. + * @returns The h-value of the indexed node. + */ + inline float h( unsigned int node ) const { return _h[ node ]; } + + /*! + * @brief Set the f-value for the given node. + * + * @param node The nav mesh node index for which the f-value is to be set. + * @param value The f-value for the given node. + */ + inline void f( unsigned int node, float value ) { if ( _inHeap[ node ] ) changeF( node, value ); else _f[ node ] = value; } + + /*! + * @brief Retrieve the f-value for the given node. + * + * @param node The nav mesh node index whose f-value is to be retrieved. + * @returns The f-value of the indexed node. + */ + inline float f( unsigned int node ) const { return _f[ node ]; } + + /*! + * @brief Change the f-value for the given node in the heap. + * + * @param node The node whose f-value is to change. + * @param value The new f-value. + */ + void changeF( unsigned int node, float value); + + /*! + * @brief Reports if the node has been visited. + * + * @param node The index of the nav mesh node to test. + * @returns True if the node has been visited, false otherwise. + */ + inline bool isVisited( unsigned int node ) const { return _visited[ node ]; } + + /*! + * @brief Reports if the node is currently in the heap. + * + * @param node The index of the nav mesh node to test. + * @returns True if the node is in the heap, false otherwise. + */ + inline bool isInHeap( unsigned int node ) const { return _inHeap[ node ]; } + + /*! + * @brief Sets the node from which this node was reached. + * + * @param dst The index of the nav mesh node reached. + * @param src The index of the nav mesh node from which dst was reached. + */ + inline void setReachedFrom( unsigned int dst, unsigned int src ) { _cameFrom[ dst ] = src; } + + /*! + * @brief Report the node from which this node was reached. + * + * @param dst The index of the nav mesh node reached. + * @returns The index of the nav mesh node from which dst was reached. + */ + inline unsigned int getReachedFrom( unsigned int dst ) const { return _cameFrom[ dst ]; } + + protected: + /*! + * @brief Resets the heap and all data. + * + * @param N The number of nodes in the nav mesh. + */ + void initialize( size_t N); + + /*! + * @brief The VALUE of the minimum keyed heap member + */ + float _minKey; + + /*! + * @brief The location of the minimum keyed heap member. + */ + unsigned int _minIdx; + + /*! + * @brief The location of the next free slot on the heap + */ + unsigned int _nextFree; + + /*! + * @brief An array of f-values for each node in the navigation mesh. + * This is a value used in the A* algorithm. The memory is + * supplied upon construction. + */ + float * _f; + + /*! + * @brief An array of g-values for each node in the navigation mesh. + * This is a value used in the A* algorithm. The memory is + * supplied upon construction. + */ + float * _g; + + /*! + * @brief An array of h-values for each node in the navigation mesh. + * This is a value used in the A* algorithm. The memory is + * supplied upon construction. + */ + float * _h; + + /*! + * @brief An array of booleans reporting if the given node is in the + * heap. The memory is supplied upon construction. + */ + bool * _inHeap; + + /*! + * @brief An array of booleans reporting if the given node has been + * visited. The memory is supplied upon construction. + */ + bool * _visited; + + /*! + * @brief An array of node indices of the nodes in the heap. + * The memory is supplied upon construction. + */ + unsigned int * _heap; + + /*! + * @brief An array of node indices which indicate how a node was + * reached. The memory is supplied upon construction. + */ + unsigned int * _cameFrom; + }; +} // namespace Menge + +#endif // __MIN_HEAP_H__ diff --git a/src/Menge/MengeCore/resources/NavMesh.cpp b/src/Menge/MengeCore/resources/NavMesh.cpp new file mode 100644 index 00000000..5565ac01 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMesh.cpp @@ -0,0 +1,542 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMesh.h" +#include "NavMeshNode.h" +#include "NavMeshEdge.h" +#include "NavMeshObstacle.h" +#include +#include "Logger.h" + +#include "BaseAgent.h" +#include "SimulatorInterface.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMesh + ///////////////////////////////////////////////////////////////////// + + const std::string NavMesh::LABEL("navmesh"); + + ///////////////////////////////////////////////////////////////////// + + NavMesh::NavMesh( const std::string & name ):Resource(name), _vCount(0), _vertices(0x0), _nCount(0), _nodes(0x0), _eCount(0), _edges(0x0), _obstCount(0), _obstacles(0x0), _nodeGroups() { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMesh::~NavMesh() { + clear(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::clear() { + if ( _vCount ) { + _vCount = 0; + delete [] _vertices; + _vertices = 0x0; + } + + if ( _nCount ) { + _nCount = 0; + delete [] _nodes; + _nodes = 0x0; + } + + if ( _eCount ) { + _eCount = 0; + delete [] _edges; + _edges = 0x0; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode & NavMesh::getNode( unsigned int i ) { + assert( i < _nCount && "Tried to access invalid node index" ); + return _nodes[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const NavMeshNode & NavMesh::getNode( unsigned int i ) const { + assert( i < _nCount && "Tried to access invalid node index" ); + return _nodes[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshEdge & NavMesh::getEdge( unsigned int i ) { + assert( i < _eCount && "Tried to access invalid edge index" ); + return _edges[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const NavMeshEdge & NavMesh::getEdge( unsigned int i ) const { + assert( i < _eCount && "Tried to access invalid edge index" ); + return _edges[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshObstacle & NavMesh::getObstacle( unsigned int i ) { + assert( i < _obstCount && "Tried to access invalid obstacle index" ); + return _obstacles[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const NavMeshObstacle & NavMesh::getObstacle( unsigned int i ) const { + assert( i < _obstCount && "Tried to access invalid obstacle index" ); + return _obstacles[ i ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float NavMesh::getElevation( unsigned int nodeID, const Vector2 & p ) const { + const NavMeshNode & node = _nodes[ nodeID ]; + return node.getElevation( p ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + Vector2 NavMesh::getGradient( unsigned int nodeID, const Vector2 & p ) const { + const NavMeshNode & node = _nodes[ nodeID ]; + return node.getGradient(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::setVertexCount( size_t count ) { + if ( _vCount ) { + delete [] _vertices; + } + _vCount = count; + _vertices = new Vector2[ _vCount ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::setVertex( unsigned int i, float x, float y ) { + assert( i < _vCount && "Accessing a vertex outside of the range of valid values." ); + _vertices[i].set( x, y ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::setNodeCount( size_t count ) { + if ( _nCount ) { + delete [] _nodes; + } + _nCount = count; + _nodes = new NavMeshNode[ _nCount ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::setEdgeCount( size_t count ) { + if ( _eCount ) { + delete [] _edges; + } + _eCount = count; + _edges = new NavMeshEdge[ _eCount ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMesh::setObstacleCount( size_t count ) { + if ( _obstCount ) { + delete [] _obstacles; + } + _obstCount = count; + _obstacles = new NavMeshObstacle[ _obstCount ]; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMesh::addGroup( const std::string & grpName, size_t grpSize ) { + if ( _nodeGroups.find( grpName ) != _nodeGroups.end() ) { + logger << Logger::ERR_MSG << "NavMesh has two groups with the same name: " << grpName << "!\n"; + return false; + } + size_t first = _nCount; + size_t last = first + grpSize - 1; + _nodeGroups[ grpName ] = NMNodeGroup( static_cast< unsigned int>( first ), static_cast< unsigned int >( last ) ); + + // Now extend the node memory + NavMeshNode * tmpNodes = new NavMeshNode[ _nCount + grpSize ]; + if ( _nCount ) { + for ( size_t i = 0; i < _nCount; ++i ) { + tmpNodes[ i ] = _nodes[ i ]; + } + delete [] _nodes; + } + _nCount += grpSize; + _nodes = tmpNodes; + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + // This disables a 64-bit compatibility warning - pushing a 64-bit value into a 32-bit value. + // In this case, I know the value in the pointers that are being re-interpreted as + // unsigned ints are REALLY just unsigned ints, so it is safe. + #pragma warning( disable : 4311 ) + #endif + bool NavMesh::finalize() { + // All of the edge indices in the nodes need to be replaced with pointers + // All of the obstacle indices in the nodes need to be replaced with pointers. + for ( size_t n = 0; n < _nCount; ++n ) { + NavMeshNode & node = _nodes[ n ]; + for ( size_t e = 0; e < node._edgeCount; ++e ) { + // TODO: This might not work in building 64-bit code. + // The pointer will be larger than the unsigned int. But as I'm pushing an unsigned + // int into a pointer slot, it'll probably be safe. Needs to be tested. + + unsigned int eID = reinterpret_cast< unsigned int >( node._edges[ e ] ); + assert( eID >= 0 && eID < _eCount && "Finalizing invalid edge id from node" ); + node._edges[ e ] = &_edges[ eID ]; + } + for ( size_t o = 0; o < node._obstCount; ++o ) { + unsigned int oID = reinterpret_cast< unsigned int >( node._obstacles[ o ] ); + assert( oID >= 0 && oID < _obstCount && "Finalizing invalid obstacle id for node" ); + node._obstacles[ o ] = &_obstacles[ oID ]; + } + node._id = static_cast< unsigned int >( n ); + node._poly.setBB( _vertices ); + } + + // All of the node indices in the edges need to be replaced with pointers + for ( size_t e = 0; e < _eCount; ++e ) { + NavMeshEdge & edge = _edges[ e ]; + unsigned int nID = reinterpret_cast< unsigned int >( edge._node0 ); + assert( nID >= 0 && nID < _nCount && "Finalizing invalid node id from edge" ); + edge._node0 = &_nodes[ nID ]; + + nID = reinterpret_cast< unsigned int >( edge._node1 ); + assert( nID >= 0 && nID < _nCount && "Finalizing invalid node id from edge" ); + edge._node1 = &_nodes[ nID ]; + // compute edge distance + edge._distance = abs( edge._node0->getCenter() - edge._node1->getCenter() ); + + // Confirm that point is on the left when looking from node0 + if ( det( edge._dir, edge._node0->_center - edge._point ) > 0.f ) { + NavMeshNode * tmp = edge._node0; + edge._node0 = edge._node1; + edge._node1 = tmp; + } + } + + std::vector< bool > processed( _obstCount, false ); + for ( unsigned int o = 0; o < (unsigned int)_obstCount; ++o ) { + _obstacles[ o ]._id = o; + if ( processed[ o ] ) continue; + const unsigned int START = o; + unsigned int curr = o; + while ( curr != NavMeshObstacle::NO_NEIGHBOR_OBST && !processed[ curr ] ) { + processed[ curr ] = true; + NavMeshObstacle & obst = _obstacles[ curr ]; + unsigned int nID = reinterpret_cast< unsigned int>( obst._node ); + assert( nID < _nCount && "Finalizing invalid node id from obstacle" ); + obst._node = &_nodes[ nID ]; + + nID = reinterpret_cast< unsigned int >( obst._nextObstacle ); + assert( ( nID < _obstCount || nID == NavMeshObstacle::NO_NEIGHBOR_OBST ) && "Finalizing invalid obstacle index for next obstacle" ); + if ( nID == NavMeshObstacle::NO_NEIGHBOR_OBST ) { + obst._nextObstacle = 0x0; + } else { + obst._nextObstacle = &_obstacles[ nID ]; + // Wire up "_prevObstacle" with the previous obstacle + _obstacles[ nID ]._prevObstacle = &_obstacles[ curr ]; + } + curr = nID; + } + // set open/closed + if ( curr == NavMeshObstacle::NO_NEIGHBOR_OBST || + curr != START ) { // set open + Agents::Obstacle * obst = &_obstacles[ START ]; + obst->setClosedState( false ); + while ( obst->_nextObstacle != 0x0 ) { + obst = obst->_nextObstacle; + obst->setClosedState( false ); + } + } + } + + return true; + } + #ifdef _WIN32 + #pragma warning( default : 4311 ) + #endif + + ////////////////////////////////////////////////////////////////////////////////////// + + //void NavMesh::addObstacles( Agents::SimulatorInterface * simulator ) { + // // Construct each contiguous obstacle + + // std::vector< bool > processed( _obstCount, false ); + // std::vector< Vector2 > vertices; + // for ( size_t o = 0; o < _obstCount; ++o ) { + // if ( processed[ o ] ) continue; + // Agents::Obstacle * start = &_obstacles[ o ]; + // Agents::Obstacle * curr = start; + // + // bool closed = true; + // while ( curr != 0x0 && !processed[ curr->_id ] ) { + // processed[ curr->_id ] = true; + // curr = curr->_nextObstacle; + // } + // + // vertices.clear(); + // // set open/closed + // if ( curr == 0x0 || + // curr != start ) { // set open + // closed = false; + // curr = start; + // while ( curr->_prevObstacle ) { + // processed[ curr->_id ] = true; + // curr = curr->_prevObstacle; + // } + // vertices.push_back( curr->getP0() ); + // while ( curr->_nextObstacle ) { + // vertices.push_back( curr->getP0() ); + // } + // vertices.push_back( curr->getP1() ); + // } else { + // vertices.push_back( curr->getP0() ); + // curr = curr->_nextObstacle; + // while ( curr != start ) { + // vertices.push_back( curr->getP0() ); + // curr = curr->_nextObstacle; + // } + // } + // // This will cause the obstacle to be considered visible to ALL agents + // // unless their obstacle set is set to 0. + // const unsigned int ALL_OBST_CLASSES = 0xffffffff; + // // Assume it's a loop + // + // //TODO: FIX THIS + // //simulator->getSpatialQuery()->addObstacle( vertices, closed, ALL_OBST_CLASSES ); + // } + //} + + ////////////////////////////////////////////////////////////////////////////////////// + + std::vector NavMesh::getObstacles() { + + //build a vector of obstaclevertexlists + std::vector obsList; + + // Construct each contiguous obstacle + std::vector< bool > processed( _obstCount, false ); + for ( size_t o = 0; o < _obstCount; ++o ) { + if ( processed[ o ] ) continue; + Agents::ObstacleVertexList obs; //temp object for the list + + + Agents::Obstacle * start = &_obstacles[ o ]; + Agents::Obstacle * curr = start; + + while ( curr != 0x0 && !processed[ curr->_id ] ) { + processed[ curr->_id ] = true; + curr = curr->_nextObstacle; + } + + + // set open/closed + if ( curr == 0x0 || + curr != start ) { // set open + obs.closed = false; + curr = start; + while ( curr->_prevObstacle ) { + processed[ curr->_id ] = true; + curr = curr->_prevObstacle; + } + obs.vertices.push_back( curr->getP0() ); + while ( curr->_nextObstacle ) { + obs.vertices.push_back( curr->getP0() ); + } + obs.vertices.push_back( curr->getP1() ); + } else { + obs.vertices.push_back( curr->getP0() ); + curr = curr->_nextObstacle; + while ( curr != start ) { + obs.vertices.push_back( curr->getP0() ); + curr = curr->_nextObstacle; + } + } + + //add it to the list + obsList.push_back(obs); + } + + return obsList; + } + + ///////////////////////////////////////////////////////////////////// + + Resource * NavMesh::load( const std::string & fileName ) { + // TODO: Change this to support comments. + std::ifstream f; + f.open( fileName.c_str(), std::ios::in ); + + if ( !f.is_open() ) { + logger << Logger::ERR_MSG << "Error opening navigation mesh file: " << fileName << "."; + return 0x0; + } + + // load vertices + unsigned int vertCount; + if ( ! ( f >> vertCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: file didn't start with an int (vertex count)."; + return 0x0; + } + + NavMesh * mesh = new NavMesh( fileName ); + mesh->setVertexCount( vertCount ); + float x, y; + for ( unsigned int v = 0; v < vertCount; ++v ) { + if ( ! ( f >> x >> y ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: format error for vertex " << ( v + 1 ) << "."; + mesh->destroy(); + return 0x0; + } + mesh->setVertex( v, x, y ); + } + + // load edges + unsigned int edgeCount; + if ( ! ( f >> edgeCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: didn't find edge count where expected."; + mesh->destroy(); + return 0x0; + } + mesh->setEdgeCount( edgeCount ); + for ( unsigned int e = 0; e < edgeCount; ++e ) { + NavMeshEdge & edge = mesh->getEdge( e ); + if ( ! edge.loadFromAscii( f, mesh->_vertices ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: format error for edge " << ( e + 1 ) << "."; + mesh->destroy(); + return 0x0; + } + } + + // load obstacles + unsigned int obstCount; + if ( ! ( f >> obstCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: didn't find obstacle count where expected."; + mesh->destroy(); + return 0x0; + } + mesh->setObstacleCount( obstCount ); + for ( unsigned int o = 0; o < obstCount; ++o ) { + NavMeshObstacle & obst = mesh->getObstacle( o ); + if ( ! obst.loadFromAscii( f, mesh->_vertices ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: format error for obstacle " << ( o + 1 ) << "."; + mesh->destroy(); + return 0x0; + } + } + + unsigned int totalN = 0; + unsigned int n = 0; + // load node group + while ( ! f.eof() ) { + std::string grpName; + if ( ! ( f >> grpName ) ) { + if ( f.eof() ) { + break; + } else { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: Missing node group name."; + mesh->destroy(); + return 0x0; + } + } + // load nodes + unsigned int nCount; + if ( ! ( f >> nCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: Node group " << grpName << " doesn't specify node count."; + mesh->destroy(); + return 0x0; + } + + totalN += nCount; + mesh->addGroup( grpName, nCount ); + assert( totalN == mesh->getNodeCount() && "Data management problem -- tracked node count does not match in-memory node count" ); + + for ( ; n < totalN; ++n ) { + NavMeshNode & node = mesh->getNode( n ); + if ( ! node.loadFromAscii( f ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: Poorly formatted definition for node " << ( n + 1 ) << "."; + mesh->destroy(); + return 0x0; + } + + node.setID( n ); + node.setVertices( mesh->getVertices() ); + } + } + + if ( !mesh->finalize() ) { + mesh->destroy(); + return 0x0; + } + return mesh; + } + + ///////////////////////////////////////////////////////////////////// + + NavMeshPtr loadNavMesh( const std::string & fileName ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &NavMesh::load, NavMesh::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No resource available."; + throw ResourceException(); + } + NavMesh * nm = dynamic_cast< NavMesh * >( rsrc ); + if ( nm == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a navigation mesh."; + throw ResourceException(); + } + + return NavMeshPtr( nm ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMesh.h b/src/Menge/MengeCore/resources/NavMesh.h new file mode 100644 index 00000000..2dbd2d6a --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMesh.h @@ -0,0 +1,445 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMesh.h + * @brief Defines the classes which maintain the navigation mesh data + */ + +#ifndef __NAV_MESH_DATA_H__ +#define __NAV_MESH_DATA_H__ + +#include "mengeCommon.h" +#include "NavMeshObstacle.h" +#include "Resource.h" +#include +#include +#include "ObstacleSets/ObstacleVertexList.h" + +namespace Menge { + + namespace Agents { + class SimulatorInterface; + } + + // forward declarations + class NavMesh; + class NavMeshNode; + class NavMeshEdge; + class NavMeshLocalizer; + class PathPlanner; + + /*! + * @brief A navigation mesh node group. + * + * It is a partitioning of the nodes in the navigation mesh + * into named groups. Each group contains a contiguous block of + * node identifiers. + */ + class NMNodeGroup { + public: + /*! + * @brief Default constructor + */ + NMNodeGroup(): _first(0), _last(0) {} + + /*! + * @brief Constructor. + * + * @param first The index of the first node included in this group. + * @param last The index of the last node included in this group. + * The group spans the nodes [ _first, _last ], inclusive. + */ + NMNodeGroup( unsigned int first, unsigned int last ): _first(first), _last(last) {} + + /*! + * @brief Reports the number of nodes in this group. + */ + inline size_t groupSize() const { return static_cast< size_t >( _last - _first + 1 ); } + + /*! + * @brief The first index in the group. + */ + unsigned int _first; + + /*! + * @brief The last index in the group. + */ + unsigned int _last; + }; + + class NavMeshFactory; + + /*! + * @brief The class for defining a navigation mesh. + * A decomposition of the free space into a connected mesh + * of convex (or near convex) polygons used for global + * planning in planar or non-planar environments. + * + * It represents the minimum data required to do path planning. + * The navigation mesh is represented in 2.5D. + * The boundaries of mesh's polygons are only defined on the ground + * plane. The nodes themselves include a definition of the polygon's + * plane off the plane. Likewise, the vertices all lie on the plane. + */ + class NavMesh : public Resource { + public: + /*! + * @brief Constructor + * + * @param name The name of the underlying navigation mesh. + */ + NavMesh( const std::string & name ); + + protected: + /*! + * @brief Destructor + */ + ~NavMesh(); + + public: + /*! + * @brief Clears the navigation mesh - removes edges and nodes. + */ + void clear(); + + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const { return LABEL; } + + //////////////////////////////////////////////////////////////// + // Getters/Setters + //////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the number of vertices in the navigation mesh. + * + * @returns The number of vertices. + */ + inline size_t getVertexCount() const { return _vCount; } + + /*! + * @brief Reports the number of nodes in the navigation mesh. + * + * @returns Thenumber of nodes. + */ + inline size_t getNodeCount() const { return _nCount; } + + /*! + * @brief Returns a reference to the ith node. + * + * @param i The index of the desired node. + * The validitity of the index is only tested + * in debug build. + * @returns A reference to the ith node. + */ + NavMeshNode & getNode( unsigned int i ); + + /*! + * @brief Returns a const reference to the ith node. + * + * @param i The index of the desired node. + * The validitity of the index is only tested + * in debug build. + * @returns A const reference to the ith node. + */ + const NavMeshNode & getNode( unsigned int i ) const; + + /*! + * @brief Reports the number of edges in the navigation mesh. + * + * @returns The integer number of edges. + */ + inline size_t getEdgeCount() const { return _eCount; } + + /*! + * @brief Returns a reference to the ith edge. + * + * @param i The index of the desired edge. + * The validitity of the index is only tested + * in debug build. + * @returns A reference to the ith edge. + */ + NavMeshEdge & getEdge( unsigned int i ); + + /*! + * @brief Returns a const reference to the ith edge. + * + * @param i The index of the desired edge. + * The validitity of the index is only tested + * in debug build. + * @returns A const reference to the ith edge. + */ + const NavMeshEdge & getEdge( unsigned int i ) const; + + /*! + * @brief Returns the number of obstacles connected to this node. + * + * @returns The number of attached obstacles. + */ + size_t getObstacleCount() const { return _obstCount; } + + /*! + * @brief Returns a reference to the ith obstacle. + * + * @param i The index of the desired obstacle. + * The validity of the index is only tested in debug build. + * @returns A reference to the ith obstacle. + */ + NavMeshObstacle & getObstacle( unsigned int i ); + + /*! + * @brief Returns a const reference to the ith obstacle. + * + * @param i The index of the desired obstacle. + * The validity of the index is only tested in debug build. + * @returns A reference to the ith obstacle. + */ + const NavMeshObstacle & getObstacle( unsigned int i ) const; + + /*! + * @brief Returns a pointer to the array of vertices. + * + * @returns The pointer to the array of vertices. + */ + inline Vector2 * getVertices() { return &_vertices[0]; } + + /*! + * @brief Returns a const pointer to the array of vertices. + * + * @returns The const pointer to the array of vertices. + */ + inline const Vector2 * getVertices() const { return &_vertices[0]; } + + //////////////////////////////////////////////////////////////// + // Geometric queries + //////////////////////////////////////////////////////////////// + + /*! + * @brief Computes the elevation at a particular point based on + * the given node's geometry. + * + * @param nodeID The node to use in computing elevation. + * @param p The point to evaluate the elevation for. + * @returns The elevation at point p based on the geometry of nodeID. + */ + float getElevation( unsigned int nodeID, const Vector2 & p ) const; + + /*! + * @brief Computes the gradient at a particular point based on + * the given node's geometry. + * + * @param nodeID The node to use in computing gradient. + * @param p The point to evaluate the gradient for. + * @returns The gradient at point p based on the geometry of nodeID. + */ + Vector2 getGradient( unsigned int nodeID, const Vector2 & p ) const; + + //////////////////////////////////////////////////////////////// + // Construction functions + //////////////////////////////////////////////////////////////// + + /*! + * @brief Parses a navigation mesh definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a NavMesh, but to a Resource. The ResourceManager + * uses it to load and instantiate VectorField instances. + * + * @param fileName The path to the file containing the NavMesh + * definition. + * @returns A pointer to the new NavMesh (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief Allocates memory for the given number of vertices. + * All previous vertices will be deleted. + * + * @param count The number of vertices. + */ + void setVertexCount( size_t count ); + + /*! + * @brief Sets the value of the ith vertex. + * + * @param i The index of the vertex. + * Validity of the index is only tested in the debug build. + * @param x The x-value of the vertex. + * @param y The y-value of the vertex. + */ + void setVertex( unsigned int i, float x, float y ); + + /*! + * @brief Allocates memory for the given number of nodes. + * All previous nodes will be deleted. + * + * @param count The number of nodes. + */ + void setNodeCount( size_t count ); + + /*! + * @brief Allocates memory for the given number of edges. + * All previous edges will be deleted. + * + * @param count The number of edges. + */ + void setEdgeCount( size_t count ); + + /*! + * @brief Allocates memory for the given number of obstacles. + * All previous obstacles will be delete.d + * + * @param count The number of obstacles. + */ + void setObstacleCount( size_t count ); + + /*! + * @brief After initializing the navigation mesh's components + * this function needs to be called to make the mesh + * functional. + */ + bool finalize(); + + /*! + * @brief Adds a group of polygons to the navigation mesh. + * + * The group name must be unique from all other group names in the navigation + * mesh. The number of polygons in the group extends the number of reported + * nodes in the mesh (see NavMesh::getNodeCount). Even if the nodes are + * not yet defined at this point, they are allocated and considered viable. + * + * @param grpName The name of the group. + * @param grpSize The number of nodes in the group. + * @returns Returns a boolean reporting success (true) or failure (false). + */ + bool addGroup( const std::string & grpName, size_t grpSize ); + + ///* + // * @brief Adds the navigation mesh's obstacles to the simulator. + // * + // * This should only be used if the navigation mesh is used as a spatial query. + // * + // * @param simulator The simulator which receives the obstacles. + // * + //void addObstacles( Agents::SimulatorInterface * simulator ); + + /*! + * @brief Gets the navigation mesh's obstacles for the simulator. + * + * @returns Vertex lists of the various obstacles + */ + std::vector getObstacles(); + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + friend class NavMeshFactory; + friend class PathPlanner; + + protected: + /*! + * @brief The number of vertices + */ + size_t _vCount; + + /*! + * @brief An array containing all vertices. + */ + Vector2 * _vertices; + + /*! + * @brief The number of nodes (aka polygons in the mesh). + */ + size_t _nCount; + + /*! + * @brief An array containing all nodes. + */ + NavMeshNode * _nodes; + + /*! + * @brief The number of edges (aka portals or shared edges between polygons). + */ + size_t _eCount; + + /*! + * @brief An array containing all edges. + */ + NavMeshEdge * _edges; + + /*! + * @brief The number of obstacles in the scene + */ + size_t _obstCount; + + /*! + * @brief An array of obstacles. + */ + NavMeshObstacle * _obstacles; + + /*! + * @brief The mapping from node group name to an instance of a NMNodeGroup. + */ + std::map< const std::string, NMNodeGroup > _nodeGroups; + }; + + /*! + * @brief The definition of the managed pointer for NavMesh data + */ + typedef ResourcePtr< NavMesh > NavMeshPtr; + + /*! + * @brief Loads the navigation mesh of the given name + * + * @param fileName The name of the file containing the navigation mesh definition. + * @returns The NavMeshPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ + NavMeshPtr loadNavMesh( const std::string & fileName ) throw ( ResourceException ); + +} // namespace Menge + +#endif // __NAV_MESH_DATA_H__ diff --git a/src/Menge/MengeCore/resources/NavMeshEdge.cpp b/src/Menge/MengeCore/resources/NavMeshEdge.cpp new file mode 100644 index 00000000..d78a7028 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshEdge.cpp @@ -0,0 +1,524 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshEdge.h" +#include "NavMeshNode.h" +#include "Logger.h" +#include "PrefVelocity.h" +#include +#include + +namespace Menge { + + /*! + * @brief The minimum width for an edge to be considered valid. + */ + const float MIN_EDGE_WIDTH = 0.00001f; + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshEdge + ///////////////////////////////////////////////////////////////////// + + NavMeshEdge::NavMeshEdge():_point(0.f,0.f), _dir(0.f,0.f), _width(0.f), _distance(0.f), _node0(0x0), _node1(0x0) { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshEdge::~NavMeshEdge() { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode * NavMeshEdge::getOtherByID( unsigned int id ) const { + assert( _node0->_id == id || _node1->_id == id && "The node indicated is not incident to this edge" ); + if ( _node0->_id == id ) { + return _node1; + } else { + return _node0; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode * NavMeshEdge::getOtherByPtr( const NavMeshNode * node ) { + assert( _node0 == node || _node1 == node && "The node indicated is not incident to this edge" ); + if ( _node0 == node) { + return _node1; + } else { + return _node0; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const NavMeshNode * NavMeshEdge::getOtherByPtr( const NavMeshNode * node ) const { + assert( _node0 == node || _node1 == node && "The node indicated is not incident to this edge" ); + if ( _node0 == node) { + return _node1; + } else { + return _node0; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float NavMeshEdge::getSqDist( const Vector2 & pt ) const { + Vector2 disp( pt - _point ); + float t = disp * _dir; + if ( t <= 0.f ) { + return absSq( disp ); + } else if ( t >= _width ) { + return absSq( pt - ( _point + _dir * _width ) ); + } else { + float dist = det( _dir, pt - _point ); + return dist * dist; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float NavMeshEdge::getSqDist( const Vector2 & pt, Vector2 & nearPt ) const { + Vector2 disp( pt - _point ); + float t = disp * _dir; + if ( t <= 0.f ) { + nearPt.set( _point ); + return absSq( disp ); + } else if ( t >= _width ) { + nearPt.set( _point + _dir * _width ); + return absSq( pt - nearPt ); + } else { + nearPt.set( _point + _dir * t ); + return absSq( pt - nearPt ); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float NavMeshEdge::getNodeDistance( float minWidth ) { + float RR = minWidth; + if ( RR > _width ) { + return -1.f; + } else { + return _distance; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshEdge::loadFromAscii( std::ifstream & f, Vector2 * vertices ) { + size_t v0, v1, n0, n1; + if ( ! ( f >> v0 >> v1 >> n0 >> n1 ) ) { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: missing edge data."; + return false; + } else { + _point.set( vertices[ v0 ] ); + Vector2 disp = vertices[ v1 ] - vertices[ v0 ]; + _width = abs( disp ); + if ( _width <= MIN_EDGE_WIDTH ) { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: edge is too narrow (width = " << _width << ")."; + return false; + } + _dir.set( disp / _width ); + // Stash indices as pointers + _node0 = ( NavMeshNode * )n0; + _node1 = ( NavMeshNode * )n1; + } + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshEdge::pointClear( const Vector2 & pos, float radius, float param ) const { + Vector2 goal( _point + param * _dir ); + Vector2 dir( norm( goal - pos ) ); + float dist = fabs( det( dir, _point - pos ) ); + if ( dist < radius ) return false; + Vector2 p1 = _point + _width * _dir; + dist = fabs( det( dir, p1 - pos ) ); + if ( dist < radius ) return false; + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + // TODO: Give a parameter which indicates a bias position -- i.e. find the point that is closest + // to this. + Vector2 NavMeshEdge::targetPoint( const Vector2 & pos, float radius ) const { + assert( _width > 2.f * radius && "Agent's radius bigger than the portal width -- can't pass through" ); + // Be smart about this + // If the position projects onto the portal, then simply find the closest point to the + // "effective" portal + // If the position lies to the left of p0 + // We simply rotate the direction from end point to test position by the appropriate + // angle. We do this as follows: + // d = || pos - p0 || + // dHat = || pos - p0 || / d + // l = sqrtf( d^2 - radius^2 ) + // cosTheta = r / d + // sinTheta = l / d + // gx = R * ( cosTheta * dHat.x + sinTheta * dHat.y ) + p0.x + // gy = R * ( cosTheta * dHat.y - sinTheta * dHat.x ) + p0.y + // If the position lies to the right of p0, it does the same computation, but with + // the opposite rotation + + // Does pos project onto the portal + Vector2 p1 = _point + _dir * _width; + Vector2 disp = pos - _point; + float dp = disp * _dir; + float mag = _width - radius; + if ( dp < radius || dp > mag ) { + if ( dp > mag ) { + disp = pos - p1; + } + float d2 = absSq( disp ); + float R2 = radius * radius; + if ( R2 > d2 ) { + // Currently overlapping the end point + if ( dp < radius ) { + return pos + _dir; + } else { + return pos - _dir; + } + } + float d = sqrtf( d2 ); + float l = sqrtf( d2 - R2 ); + float cTheta = radius / d; + float sTheta = l / d; + float x, y; + if ( dp < radius ) { + x = cTheta * disp.x() + sTheta * disp.y(); + y = cTheta * disp.y() - sTheta * disp.x(); + } else { + x = cTheta * disp.x() - sTheta * disp.y(); + y = cTheta * disp.y() + sTheta * disp.x(); + } + Vector2 goal( x, y ); + goal *= radius / d; + if ( dp < radius ) { + return goal + _point; + } else { + return goal + p1; + } + } else { + return _point + _dir * dp; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + Vector2 NavMeshEdge::getClearDirection( const Vector2 & pos, float radius, const Vector2 & dir ) const { + assert( _width > 2.f * radius && "Agent's radius bigger than the portal width -- can't pass through" ); + /* + The algorithm seeks to find the direction, closest to the given direction (dir) but doesn't lead to + collisions with the portal endpoints (and, therefore, the adjacent obstacles). + + It does so in the following manner. + + _ + P0 /| P1 + o------------------------------------o + \ / + \ / + \ / + \ / dir + \ / + \/ + / + o + pos + + ASSUMPTIONS: + 1) the provided direction intersects the portal between p0 and p1 + 2) pos, P0 and P1 are not co-linear. + 3) The input direction is NOT normalized. + + First, it determines if moving the given direction will bring it closer to the end points than radius + distance (shown w.r.t. P0). + This is a two-part test. Given the line passing through pos in the direction of dir, it determines the + distance of each portal endpoint to this line. If the distance > agent radius, then it's fine. + HOWEVER, just because the distance is less than the radius does NOT mean it's necessarily bad. For example, + if the agent is moving AWAY from the point, then the point can approach the line from behind. + - this is detected by determining if the projection lies on the opposite side of the point, pos, than + the movement. + If the distance > radius, or the projection is "behind" the agent, the path is clear and the preferred + direction is returned. + + If it isn't clear, then a clear direction must be computed. A direction is computed from pos to a point Q + on a circle positioned at each end point (P0 and P1). The tangent point is defined such that the line + connecting Q and pos is tangent to the circle AND intersects the portal between P0 and P1 (generally, there + are two lines passing through pos and tangent to the circle, but one must, by definition point outside + of the portal). It is computed by rotatining the vector TO the end point such that it becomes tangent. + The direction to P0 is rotated to the right and the direction to P1 is rotated to the left. + + The two directions define a cone which spans the passable region of directions.. If the cone is well + formed (i.e. the right limit is on the right side of the left limit) then a valid direction exists. + In that case, the preferred direction must lie outside of the cone (if it lies inside, then the original test + would have already passed). So, if the preferred direction lies to the left of the cone, we return the + left limit. If it lies to the right of the cone, we return the right limit. + + If the cone is not well-formed, it is because the agent's position does not project onto the portal and + it is coming at the portal at an oblique angle. As such, there is no direction which will take it straight + through the portal. Instead, we'll take the direction that will have it clear the nearest end point. + */ + + // Test to see if goal direction is valid + const float dirMag2 = absSq( dir ); + const float threshold = radius * radius * dirMag2; + Vector2 p0Delta = _point - pos; + float dist = det( dir, p0Delta ); + if ( dist * dist >= threshold || p0Delta * dir < 0.f ) { + Vector2 p1Delta = _point + _width * _dir - pos; + dist = det( dir, p1Delta ); + if ( dist * dist >= threshold || p1Delta * dir < 0.f ) { + return norm( dir ); + } + } + + // Directions towards portal's PHYSICAL endpoints + Vector2 d0 = _point - pos; + Vector2 p1 = _point + _dir * _width; + Vector2 d1 = p1 - pos; + Vector2 portalDir( _dir ); + if ( det( d1, d0 ) < 0.f ) { + // make sure that d0 is on the left and d1 is on the right + Vector2 tmp( d0 ); + d0.set( d1 ); + d1.set( tmp ); + portalDir.negate(); + } + + // compute left extent of passable cone + float d = abs( d0 ); + Vector2 dHat0 = d0 / d; + if ( d <= radius ) { + // assume I can only overlap one edge at a time. + Vector2 N( dHat0.y(), -dHat0.x() ); + if ( N * dir >= 0.f ) { + return N; + } else { + return -N; + } + } + float l = sqrtf( d * d - radius * radius ); + float sinTheta0 = radius / d; + float cosTheta0 = l / d; + float dx = cosTheta0 * dHat0.x() + sinTheta0 * dHat0.y(); + float dy = cosTheta0 * dHat0.y() - sinTheta0 * dHat0.x(); + Vector2 leftLimit( dx, dy ); + + // Compute right extent of passable cone + d = abs( d1 ); + Vector2 dHat1( d1 / d ); + if ( d <= radius ) { + Vector2 N( dHat1.y(), -dHat1.x() ); + if ( N * dir >= 0.f ) { + return N; + } else { + return -N; + } + } + l = sqrtf( d * d - radius * radius ); + float cosTheta1 = l / d; + float sinTheta1 = radius / d; + dx = cosTheta1 * dHat1.x() - sinTheta1 * dHat1.y(); + dy = cosTheta1 * dHat1.y() + sinTheta1 * dHat1.x(); + + Vector2 rightLimit( dx, dy ); + if ( det( rightLimit, leftLimit ) < 0 ) { + // The cone spans no valid directions. + // No direct path exists - simply clear the nearer endpoint + if ( leftLimit * portalDir >= 0.f ) { + // the left end point is the near goal + return leftLimit; + } else { + // the right end point is the near goal + } + return Vector2( dx, dy ); + } else { + if ( det( leftLimit, dir ) > 0 ) { + // The preferred direction lies left of the left extent the cone + return leftLimit; + } else { + // The preferred direction lies right of the right extent the cone + return rightLimit; + } + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMeshEdge::setClearDirections( const Vector2 & pos, float radius, const Vector2 & dir, Agents::PrefVelocity & pVel ) const { + assert( _width > 2.f * radius && "Agent's radius bigger than the portal width -- can't pass through" ); + /* + The algorithm seeks to find the direction, closest to the given direction (dir) but doesn't lead to + collisions with the portal endpoints (and, therefore, the adjacent obstacles). + + It does so in the following manner. + + _ + P0 /| P1 + o------------------------------------o + \ / + \ / + \ / + \ / dir + \ / + \/ + / + o + pos + + ASSUMPTIONS: + 1) the provided direction intersects the portal between p0 and p1 + 2) pos, P0 and P1 are not co-linear. + 3) The input direction is NOT normalized. + + First, it determines if moving the given direction will bring it closer to the end points than radius + distance (shown w.r.t. P0). + This is a two-part test. Given the line passing through pos in the direction of dir, it determines the + distance of each portal endpoint to this line. If the distance > agent radius, then it's fine. + HOWEVER, just because the distance is less than the radius does NOT mean it's necessarily bad. For example, + if the agent is moving AWAY from the point, then the point can approach the line from behind. + - this is detected by determining if the projection lies on the opposite side of the point, pos, than + the movement. + If the distance > radius, or the projection is "behind" the agent, the path is clear and the preferred + direction is returned. + + If it isn't clear, then a clear direction must be computed. A direction is computed from pos to a point Q + on a circle positioned at each end point (P0 and P1). The tangent point is defined such that the line + connecting Q and pos is tangent to the circle AND intersects the portal between P0 and P1 (generally, there + are two lines passing through pos and tangent to the circle, but one must, by definition point outside + of the portal). It is computed by rotatining the vector TO the end point such that it becomes tangent. + The direction to P0 is rotated to the right and the direction to P1 is rotated to the left. + + The two directions define a cone which spans the passable region of directions.. If the cone is well + formed (i.e. the right limit is on the right side of the left limit) then a valid direction exists. + In that case, the preferred direction must lie outside of the cone (if it lies inside, then the original test + would have already passed). So, if the preferred direction lies to the left of the cone, we return the + left limit. If it lies to the right of the cone, we return the right limit. + + If the cone is not well-formed, it is because the agent's position does not project onto the portal and + it is coming at the portal at an oblique angle. As such, there is no direction which will take it straight + through the portal. Instead, we'll take the direction that will have it clear the nearest end point. + */ + + // Directions towards portal's PHYSICAL endpoints + Vector2 d0 = _point - pos; + Vector2 p1 = _point + _dir * _width; + Vector2 d1 = p1 - pos; + Vector2 portalDir( _dir ); + if ( det( d1, d0 ) < 0.f ) { + // make sure that d0 is on the left and d1 is on the right + Vector2 tmp( d0 ); + d0.set( d1 ); + d1.set( tmp ); + portalDir.negate(); + } + + const float R2 = radius * radius; + // compute left extent of passable cone + float d2 = absSq( d0 ); + if ( d2 < R2 ) { + // Already colliding with the left portal edge + // If the portal is wide enough to allow the agent through, I can't collide with + // both. So, this is the only possible collision. + // Simply move parallel with the portal (into the opening) to get out of collision + pVel.setSingle( portalDir ); + return; + } + // This represents refactored algebra. + float l = sqrtf( d2 - R2 ); + float sinTheta0 = radius; + float cosTheta0 = l; + float dx = cosTheta0 * d0._x + sinTheta0 * d0._y; + float dy = cosTheta0 * d0._y - sinTheta0 * d0._x; + Vector2 leftLimit( dx / d2, dy / d2 ); + + // Compute right extent of passable cone + d2 = absSq( d1 ); + if ( d2 <= R2 ) { + pVel.setSingle( -portalDir ); + return; + } + l = sqrtf( d2 - R2 ); + float cosTheta1 = l; + float sinTheta1 = radius; + dx = cosTheta1 * d1._x - sinTheta1 * d1._y; + dy = cosTheta1 * d1._y + sinTheta1 * d1._x; + Vector2 rightLimit( dx / d2, dy / d2 ); + + if ( det( rightLimit, leftLimit ) < 0 ) { + // The cone spans no valid directions. + // No direct path exists - simply clear the nearer endpoint + if ( leftLimit * portalDir >= 0.f ) { + // the left end point is the near goal + pVel.setSingle( leftLimit ); + } else { + // the right end point is the near goal + pVel.setSingle( rightLimit ); + } + } else { + Vector2 prefDir; + + if ( det( leftLimit, dir ) > 0 ) { + // The preferred direction lies left of the left extent the cone + prefDir.set( leftLimit ); + } else if ( det( dir, rightLimit ) > 0 ) { + // The preferred direction lies right of the right extent the cone + prefDir.set( rightLimit ); + } else { + prefDir.set( norm( dir ) ); + } + pVel.setSpan( leftLimit, rightLimit, prefDir ); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshEdge::pointOnLeft( unsigned int id ) const { + assert( id == _node0->getID() || id == _node1->getID() && "Given node is not attached to this edge" ); + return id == _node0->getID(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshEdge::pointOnLeft( const NavMeshNode * node ) const { + assert( node == _node0 || node == _node1 && "Given node is not attached to this edge" ); + return node == _node0; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMeshEdge.h b/src/Menge/MengeCore/resources/NavMeshEdge.h new file mode 100644 index 00000000..7325519b --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshEdge.h @@ -0,0 +1,408 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMeshEdge.h + * @brief Defines the "edge" of the adjacency graph in a navigation mesh. + * + * The connectivity edge is uniquely associated with a "portal", + * the shared edge between two adjacent polygons. + */ + +#ifndef __NAV_MESH_EDGE_H__ +#define __NAV_MESH_EDGE_H__ + +#include +#include "mengeCommon.h" + + namespace Menge { + + // Forward declarations + class NavMesh; + class NavMeshNode; + namespace Agents { + class PrefVelocity; + } + + /*! + * @brief The navigation mesh adjacency graph edge. + * + * It is comprised of + * two parts: the portal geometry and the logical graph connectivity. + * A NavMeshEdge exists because two navigation mesh polygons share + * a common edge. The portal geometry is the edge. The graph + * connectivity indicates that the two mesh polygons (nodes) are + * connected in the logical graph. + */ + class NavMeshEdge { + public: + /*! + * @brief Constructor + */ + NavMeshEdge(); + + /*! + * @brief Destructor + */ + ~NavMeshEdge(); + + /*! + * @brief Returns the first edge point. + * + * @returns The 2D value of the first edge end point + */ + inline Vector2 getP0() const { return _point; } + + /*! + * @brief Returns a point inset from the first end point. + * + * @param dist The inset distance. + * @returns The 2D value of the point inset dist from the first edge end point + */ + inline Vector2 getP0( float dist ) const { return _point + _dir * dist; } + + /*! + * @brief Returns the second edge point. + * + * @returns The 2D value of the second edge end point + */ + inline Vector2 getP1() const { return _point + _dir * _width; } + + /*! + * @brief Returns a point inset from the second end point. + * + * @param dist The inset distance. + * @returns The 2D value of the point inset dist from the second edge end point + */ + inline Vector2 getP1( float dist ) const { return _point + _dir * (_width - dist); } + + /*! + * @brief Returns the direction of the edge. + * + * @returns The edge's direction. + */ + inline Vector2 getDirection() const { return _dir; } + + /*! + * @brief Returns the first attached NavMeshNode + * + * @returns A pointer to the first navigation mesh node. + */ + NavMeshNode * getFirstNode() const { return _node0; } + + /*! + * @brief Returns a pointer to the node on the opposite end + * of the edge from the given node (by id). + * + * If the given node is not actually adjacent to the edge, then the + * first adjacent node is returned. + * + * @param id The identifier of the operand node. + * @returns A pointer to the node on the other side of the edge. + */ + NavMeshNode * getOtherByID( unsigned int id ) const; + + /*! + * @brief Returns a pointer to the node on the opposite end + * of the edge from the given node (by pointer). + * + * If the given node is not actually adjacent to the edge, then the + * first adjacent node is returned. + * + * @param node A pointer to the operand node. + * @returns A pointer to the node on the other side of the edge. + */ + NavMeshNode * getOtherByPtr( const NavMeshNode * node ); + + /*! + * @brief Returns a const pointer to the node on the opposite end + * of the edge from the given node (by pointer). + * + * If the given node is not actually adjacent to the edge, then the + * first adjacent node is returned. + * + * @param node A pointer to the operand node. + * @returns A const pointer to the node on the other side of the edge. + */ + const NavMeshNode * getOtherByPtr( const NavMeshNode * node ) const; + + + + ////////////////////////////////////////////////////////////////////////// + // Getters/setters + ////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Sets the edge's point value. + * + * @param p The point value to set. + */ + inline void setPoint( const Vector2 & p ) { _point.set( p ); } + + /*! + * @brief Sets the edge's direction value. + * + * @param d The direction value to set. It is assumed to be + * normalized and is not tested. + */ + inline void setDirection( const Vector2 & d ) { _dir.set( d ); } + + /*! + * @brief Sets the edge's width value. + * + * @param w The width value to set. + */ + inline void setWidth( float w ) { _width = w; } + + /*! + * @brief Reports the width of the edge. + * + * @returns The width of the edge. + */ + inline float getWidth() const { return _width; } + + /*! + * @brief Sets the connected node pointers. + * + * @param n0 The pointer to the first connected node. + * @param n1 The pointer to the second connected node. + */ + inline void setNodes( NavMeshNode * n0, NavMeshNode * n1 ) { _node0 = n0; _node1 = n1; } + + ///////////////////////////////////////////////////////////////////////////// + // Geometric queries + ///////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Selects a point along the edge + * + * @param t The parameter from _point in the edge direction. + * @returns The point which is: _point + t * _dir; + */ + inline Vector2 getPoint( float t ) const { return _point + t * _dir; } + + /*! + * @brief Reports if the point q = _point + param * _dir is + * clear for an agent with the given radius positioned at pos. + * "Clear" means a straight-line path will not cause it to intersect + * the ends of the edge. + * + * @param pos The position of the agent. + * @param radius The radius of the agent. + * @param param The parameter, along the edge's direction, of the + * desired goal point. + * @returns A boolean reporting if the straight line path is clear (true) or + * occlued (false). + */ + bool pointClear( const Vector2 & pos, float radius, float param ) const; + + /*! + * @brief Computes a target point with respect to this edge. The target point + * is a point along the line of the edge to which the agent with the + * given radius can head straight towards and be guaranteed NOT to + * intersect with the end points of the edge. It also leads the agent + * to get closer to crossing the edge. + * + * @param pos The position from which to compute nearest point. + * @param radius The radius of the agent -- required clearance. + * @returns A point which represents the goal point the agent should walk + * towards to clear the obstacles and pass through the edge. + */ + Vector2 targetPoint( const Vector2 & pos, float radius ) const; + + /*! + * @brief Computes the collision-free velocity towards the portal based on the + * agent radius and the preferred direction. If the preferred direction + * is collision free, it is returned. Otherwise, the "best" collision-free + * approximation of that direction is returned. + * + * @param pos The position of the agent. + * @param radius The radius of the agent. + * @param dir Preferred direction of the agent. Direction is NOT assumed to + * be of unit-length. + * @returns The collision-free direction that best approximates the preferred + * direction (may be the preferred direction). + */ + Vector2 getClearDirection( const Vector2 & pos, float radius, const Vector2 & dir ) const; + + /*! + * @brief Sets the directions of a preferred velocity that passes through the + * edge biased towards the indicated direction. + * + * If approaching the portal obliquely, the preferred direction may not provide + * sufficient clearance. In this case, the direction is changed so the agent makes + * progress toward the portal without colliding with the portal limits. + * + * At the same time, sets the limits of the preferred velocity based on the + * actual clearance. + * + * @param pos The position of the agent. + * @param radius The radius of the agent. + * @param dir Preferred direction of the agent. Direction is NOT assumed to + * be of unit-length. + * @param pVel The preferred velocity whose directions are set. + */ + void setClearDirections( const Vector2 & pos, float radius, const Vector2 & dir, Agents::PrefVelocity & pVel ) const; + + /*! + * @brief Reports the squared distance to the edge from the given point. + * + * @param pt The point to compute from. + * @returns The squared distance between p and the nearest point on the edge. + */ + float getSqDist( const Vector2 & pt ) const; + + /*! + * @brief Reports the squared distance to the edge from the given point + * and gives the nearest point. + * + * @param pt The point to compute from. + * @param nearPt The nearest point to pt on the edge. The values of + * this vector will be changed by the function + * @returns The squared distance between p and the nearest point on the edge. + */ + float getSqDist( const Vector2 & pt, Vector2 & nearPt ) const; + + /*! + * @brief Reports the distance to the edge from the given point. + * + * @param pt The point to compute from. + * @returns The squared distance between p and the nearest point on the edge. + */ + float getDist( const Vector2 & pt ) const { return sqr( getSqDist( pt ) ); } + + /*! + * @brief Computes the width-dependent distance between the + * two nodes connected by this edge. + * If the edge width is narrower than the given minimum width + * the distance is "infinite" (indicated by -1). Otherwise + * it is the distance between node centers. + * + * @param minWidth The minimum required width. + * @returns The passable distance between the two nodes. + */ + float getNodeDistance( float minWidth ); + + /*! + * @brief Return the Euclidian distance between the two + * nodes this edge connects. + * + * @returns The distance between the two connected node's centers. + */ + inline float getNodeDistance() const { return _distance; } + + /*! + * @brief Sets the edge properties from an edge definition + * in the given ascii file stream. + * + * @param f The input file stream. + * @param vertices The array of vertices into which the definition + * indexes. + * @returns A boolean indicating successful parsing (true) or failure + * (false). + */ + bool loadFromAscii( std::ifstream & f, Vector2 * vertices ); + + /*! + * @brief Reports if _point in this edge is on the left for + * the node with the given id. + * + * @param id The id of the node to test. (The id is assumed + * to be connected. It is only checked in debug mode.) + * @returns A boolean reporting if the point in the edge is on the left + * when facing the edge from the node with the given id. + */ + bool pointOnLeft( unsigned int id ) const; + + /*! + * @brief Reports if _point in this edge is on the left + * when looked at from within the given node. + * + * @param node The pointer to the node to test. (The id is assumed + * to be connected. It is only checked in debug mode.) + * @returns A boolean reporting if the point in the edge is on the left + * when facing the edge from the node with the given id. + */ + bool pointOnLeft( const NavMeshNode * node ) const; + + friend class NavMesh; + + protected: + // Geometry of the edge's portal + /*! + * @brief The point that defines the portal geometry. The portal + * is defined as p(t) = _point + t * _dir, t in the range [0, _width] + */ + Vector2 _point; + + /*! + * @brief The unit-length direction of the portal. See _point + * for how the portal is defined w.r.t. this field member. + */ + Vector2 _dir; + + /*! + * @brief The width of the portal. + */ + float _width; + + // Logical connectivity data + /*! + * @brief The "distance" between the two nodes connected by this edge. + * Used to estimate the cost of a path (the length of the path). + */ + float _distance; + + // TODO: Does lower-indexed/upper-indexed really matter? + /*! + * @brief A pointer to the first nav mesh node connected by + * this edge. When standing in this node, the edge's _point + * is on the left. + */ + NavMeshNode * _node0; + + /*! + * @brief A pointer to the second nav mesh node connected by + * this edge. When standing in this node, the edge's _point + * is on the right. + */ + NavMeshNode * _node1; + }; +} // namespace Menge + +#endif // __NAV_MESH_EDGE_H__ diff --git a/src/Menge/MengeCore/resources/NavMeshLocalizer.cpp b/src/Menge/MengeCore/resources/NavMeshLocalizer.cpp new file mode 100644 index 00000000..a2303275 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshLocalizer.cpp @@ -0,0 +1,313 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshLocalizer.h" +#include "NavMeshNode.h" +#include "PortalPath.h" +#include "BaseAgent.h" +#include "PathPlanner.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshLocation + ///////////////////////////////////////////////////////////////////// + + const unsigned int NavMeshLocation::NO_NODE = std::numeric_limits< unsigned int >::max(); + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocation::setNode( unsigned int nodeID ) { + if ( _hasPath ) { + delete _path; + _hasPath = false; + } + _nodeID = nodeID; + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocation::clearPath() { + if ( _hasPath ) { + unsigned int node = _path->getNode(); + delete _path; + _hasPath = false; + _nodeID = (size_t)node; + } + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocation::getNode() const { + //TODO: NavMesh nodes should simply be size_ts and NOT unsigned ints. + if ( _hasPath ) { + return (unsigned int)_path->getNode(); + } else { + return (unsigned int)_nodeID; + } + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocation::setPath( PortalPath * path ) { + if ( _hasPath ) { + delete _path; + } + _path = path; + _hasPath = true; + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of NavMeshLocalizer + ///////////////////////////////////////////////////////////////////// + + const std::string NavMeshLocalizer::LABEL("navmesh_localizer"); + + ///////////////////////////////////////////////////////////////////// + + NavMeshLocalizer::NavMeshLocalizer( const std::string & name ): Resource(name), _navMesh(0x0),_trackAll(false),_planner(0x0) { + try { + _navMesh = loadNavMesh( name ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate navigation mesh localizer for navigation mesh: " << name << "."; + throw ResourceException(); + } + const size_t NODE_COUNT = _navMesh->getNodeCount(); + _nodeOccupants = new OccupantSet[ NODE_COUNT + 1 ]; + } + + ///////////////////////////////////////////////////////////////////// + + NavMeshLocalizer::~NavMeshLocalizer() { + delete [] _nodeOccupants; + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocalizer::clearPath( size_t agentID ) { + _locLock.lockRead(); + if ( _locations.count( agentID ) > 0 ) { + _locations[ agentID ].clearPath(); + } + _locLock.releaseRead(); + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocalizer::getNode( const Agents::BaseAgent * agent ) const { + unsigned int node = NavMeshLocation::NO_NODE; + _locLock.lockRead(); + if ( _locations.count( agent->_id ) > 0 ) { + node = _locations[ agent->_id ].getNode(); + } + _locLock.releaseRead(); + return node; + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocalizer::getNode( const Vector2 & p ) const { + return findNodeBlind( p ); + } + + ///////////////////////////////////////////////////////////////////// + + PortalPath * NavMeshLocalizer::getPath( size_t id ) { + PortalPath * path = 0x0; + _locLock.lockRead(); + if ( _locations.count( id ) > 0 ) { + if ( _locations[ id ].isPath() ) { + path = _locations[ id ]._path; + } + } + _locLock.releaseRead(); + return path; + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocalizer::setPath( size_t agentID, PortalPath * path ) { + _locLock.lockWrite(); + _locations[ agentID ].setPath( path ); + _locLock.releaseWrite(); + } + + ///////////////////////////////////////////////////////////////////// + + void NavMeshLocalizer::setNode( size_t agentID, unsigned int nodeID ) { + _locLock.lockWrite(); + _locations[ agentID ].setNode( nodeID ); + _locLock.releaseWrite(); + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocalizer::updateLocation( const Agents::BaseAgent * agent, bool force ) const { + const size_t ID = agent->_id; + // NOTE: This will create a default location instance if the agent didn't already + // have one + _locLock.lockRead(); + NavMeshLocation & loc = _locations[ ID ]; + _locLock.releaseRead(); + unsigned int oldLoc = loc.getNode(); + unsigned int newLoc = oldLoc; + if ( loc._hasPath ) { + newLoc = loc._path->updateLocation( agent, _navMesh, this, _planner ); + } else { //if ( _trackAll || force ) { + const Vector2 & p = agent->_pos; + unsigned int oldNode = (unsigned int)loc._nodeID; + if ( loc._nodeID == NavMeshLocation::NO_NODE ) { + loc._nodeID = findNodeBlind( p ); + } else { + const NavMeshNode & node = _navMesh->getNode( (unsigned int)loc._nodeID ); + if ( ! node.containsPoint( p ) ) { // not in current node + loc._nodeID = testNeighbors( node, p ); + if ( loc._nodeID == NavMeshLocation::NO_NODE ) { + loc._nodeID = findNodeBlind( p ); + } + } + } + if ( loc._nodeID == NavMeshLocation::NO_NODE ) { + loc._nodeID = oldNode; + } + newLoc = (unsigned int)loc._nodeID; + } + + if ( newLoc != oldLoc ) { + if ( newLoc == NavMeshLocation::NO_NODE ) { + newLoc = static_cast< unsigned int>( _navMesh->getNodeCount() ); + } + + // remove the agent from the set for oldLoc and place it in newLoc + #pragma omp critical( NAV_MESH_LOCALIZER_MOVE_AGENT ) + { + if ( oldLoc != NavMeshLocation::NO_NODE ) { + OccupantSetItr fromItr = _nodeOccupants[ oldLoc ].find( ID ); + if ( fromItr != _nodeOccupants[ oldLoc ].end() ) { + _nodeOccupants[ oldLoc ].erase( fromItr ); + } else if ( oldLoc != NavMeshLocation::NO_NODE ) { + logger << Logger::ERR_MSG << "Trying to remove agent " << ID << " from node " << oldLoc << " but it has not been assigned to that node."; + const size_t NCOUNT = _navMesh->getNodeCount(); + for ( size_t i = 0; i < NCOUNT; ++i ) { + fromItr = _nodeOccupants[ i ].find( ID ); + if ( fromItr != _nodeOccupants[ i ].end() ) { + logger << "\n\tFound the agent in node: " << i << "."; + _nodeOccupants[ i ].erase( fromItr ); + break; + } + } + } + } + _nodeOccupants[ newLoc ].insert( ID ); + } + } + + return newLoc; + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocalizer::findNodeBlind( const Vector2 & p, float tgtElev ) const { + const unsigned int nCount = static_cast< unsigned int >( _navMesh->getNodeCount() ); + float elevDiff = 1e6f; + unsigned int maxNode = NavMeshLocation::NO_NODE; + for ( unsigned int n = 0; n < nCount; ++n ) { + const NavMeshNode & node = _navMesh->getNode( n ); + if ( node.containsPoint( p ) ) { + float hDiff = fabs( node.getElevation( p ) - tgtElev ); + if ( hDiff < elevDiff ) { + maxNode = n; + elevDiff = hDiff; + } + } + } + return maxNode; + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int NavMeshLocalizer::testNeighbors( const NavMeshNode & node, const Vector2 & p ) const { + const unsigned int nCount = static_cast< unsigned int>( node.getNeighborCount() ); + for ( unsigned int n = 0; n < nCount; ++n ) { + const NavMeshNode * nbr = node.getNeighbor( n ); + if ( nbr->containsPoint( p ) ) { + return nbr->getID(); + } + } + return NavMeshLocation::NO_NODE; + } + + ///////////////////////////////////////////////////////////////////// + + Resource * NavMeshLocalizer::load( const std::string & fileName ) { + NavMeshPtr mesh; + try { + mesh = loadNavMesh( fileName ); + } catch ( ResourceException ) { + return 0x0; + } + NavMeshLocalizer * nml = new NavMeshLocalizer( fileName ); + nml->_navMesh = mesh; + return nml; + } + + ///////////////////////////////////////////////////////////////////// + + NavMeshLocalizerPtr loadNavMeshLocalizer( const std::string & fileName, bool usePlanner ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &NavMeshLocalizer::load, NavMeshLocalizer::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No resource available."; + throw ResourceException(); + } + NavMeshLocalizer * nml = dynamic_cast< NavMeshLocalizer * >( rsrc ); + if ( nml == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a navigation mesh localizer."; + throw ResourceException(); + } + + if ( usePlanner ) { + if ( nml->getPlanner() == 0x0 ) { + PathPlanner * planner = new PathPlanner( nml->getNavMesh() ); + nml->setPlanner( planner ); + } + } + + return NavMeshLocalizerPtr( nml ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMeshLocalizer.h b/src/Menge/MengeCore/resources/NavMeshLocalizer.h new file mode 100644 index 00000000..1c057846 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshLocalizer.h @@ -0,0 +1,437 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMeshLocalizer.h + * @brief Data structure responsible for knowing where on the navigation mesh + * each agent is located. + */ + +#ifndef __NAV_MESH_LOCALIZER_H__ +#define __NAV_MESH_LOCALIZER_H__ + +#include "NavMesh.h" +#include "NavMeshNode.h" +#include "mengeCommon.h" +#include "Resource.h" +#include "ReadersWriterLock.h" +#include +#include + +namespace Menge { + + namespace Agents { + class BaseAgent; + } + + // Forward declaration + class PortalPath; + class PathPlanner; + + /*! + * @brief Class for indicating how the location of the agent is defined. + * Either by a portal path or a node. + */ + class NavMeshLocation { + public: + /*! + * @brief Default constructor + */ + NavMeshLocation():_nodeID(NO_NODE),_hasPath(false){} + + /*! + * @brief Constructor + * Initializes the location to being a node id. + * + * @param nodeID The identifier of a nav mesh node. + */ + NavMeshLocation( unsigned int nodeID ):_nodeID(nodeID), _hasPath(false){} + + /*! + * @brief Constructor + * Initializes the location to being a path. + * The NavMeshLocation takes responsibility for deleting the path. + * + * @param path A pointer to a path. This class takes responsibility + * for freeing the memory. + */ + NavMeshLocation( PortalPath * path ):_path(path), _hasPath(true) {} + + /*! + * @brief Sets the current position to being a node. + * + * @param nodeID The identifier of the navigation mesh node + * for the location. If the location was previously + * a path, the path is deleted. + */ + void setNode( unsigned int nodeID ); + + /*! + * @brief Clears the path (if any), maintaining the node location. + */ + void clearPath(); + + /*! + * @brief Reports the node the agent is currently in. + * + * @returns The index of the node associated with this location. + * If the location is not on a node, PortalPath::NO_NODE is returned. + */ + unsigned int getNode() const; + + /*! + * @brief Sets the current position to being the given path. + * + * @param path The path for defining the current location. + * The locator takes responsibility for deleting the + * path. + */ + void setPath( PortalPath * path ); + + /*! + * @brief Reports if the location is a path. + * + * @returns True if the location is a path, false if a node. + */ + inline bool isPath() const { return _hasPath; } + + /*! + * @brief Reports if the location is a node. + * + * @returns True if the location is a node, false if a path. + */ + inline bool isNode() const { return !_hasPath; } + + /*! + * @brief Location information. If the agent has a path it is a + * pointer to that path. Otherwise, it is an index into + * the navigation mesh. + */ + union { + size_t _nodeID; + PortalPath * _path; + }; + + /*! + * @brief Determines interpretation of the location union. If true, + * _path contains a pointer. Otherwise, _nodeID is an index + * in the navigation mesh. + */ + bool _hasPath; + + /*! + * @brief Signal for indicating that the position is NOT on the + * navigation mesh. + */ + const static unsigned int NO_NODE; + }; + + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief A collection of agent ids. + * It represents the population of each nav mesh node. + */ + typedef std::set< size_t > OccupantSet; + + /*! + * @brief Iterator for an OccupantSet. + */ + typedef OccupantSet::iterator OccupantSetItr; + + /*! + * @brief Const iterator for an OccupantSet. + */ + typedef OccupantSet::const_iterator OccupantSetCItr; + + /*! + * @brief Class responsible for tracking agent relatinoships to the + * navigation mesh: its current location and its path. + */ + class MENGE_API NavMeshLocalizer : public Resource { + public: + /*! + * @brief Constructor + * + * @param name The name of the underlying navigation mesh. + */ + NavMeshLocalizer( const std::string & name ); + + protected: + /*! + * @brief Destructor + */ + ~NavMeshLocalizer(); + + public: + + + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const { return LABEL; } + + /*! + * @brief Reports the node the agent is currently in. + * + * @param agent The agent whose position relative to the nav + * mesh is returned. + * @returns The index of the node associated with this location. + * If the location is not on a node, NavMeshLocation::NO_NODE is returned. + */ + unsigned int getNode( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Reports the node with the highest elevation for the given point. + * + * @param p The point to test against the mesh. + * @returns The index of the node associated with this location. + * If the location is not on a node, NavMeshLocation::NO_NODE is returned. + */ + unsigned int getNode( const Vector2 & p ) const; + + /*! + * @brief Returns the NavMeshNode of the given id. + * + * @param i The index of the desired mesh node. + * @returns A copy the specified mesh node. + */ + const NavMeshNode getNode( unsigned int i ) { return _navMesh->getNode( i ); } + + /*! + * @brief Retrieves the path for the given agent. + * + * @param id The identifier for the agent. + * @returns A pointer to the PortalPath for the agent. If the agent is not currently + * following a path, NULL is returned. + */ + PortalPath * getPath( size_t id ); + + /*! + * @brief Sets the path for the given agent. + * + * @param agentID The index of the agent for whom the path is set. + * @param path The path for the agent. + */ + void setPath( size_t agentID, PortalPath * path ); + + /*! + * @brief Clears the path for the given agent. + * + * @param agentID The index of the agent whose path is to be cleared. + */ + void clearPath( size_t agentID ); + + /*! + * @brief Sets the location of the agent to be anode + * + * @param agentID The index of the agent to update. + * @param nodeID The index of the node. + */ + void setNode( size_t agentID, unsigned int nodeID ); + + /*! + * @brief Sets the tracking status of the localizer to all agents. + * + * By default, the localizer only tracks agents on paths. + * Calling this function will cause all agents to be tracked, + * even if they are not currently following navigation mesh + * paths. However, it can't be set back. + */ + void setTrackAll() { _trackAll = true; } + + /*! + * @brief Updates the location of the agent relative to the nav mesh. + * + * @param agent The agent whose location is updated. + * @param force Force causes the update regardless of whether + * the localizer is set to track all or not. + * @returns The index of the node in which the agent is found. If it is not + * on the navigation mesh, NavMeshLocation::NO_NODE is returned. + */ + unsigned int updateLocation( const Agents::BaseAgent * agent, bool force=false ) const; + + /*! + * @brief Set the path planner for the localizer. + * + * @param planner The path planner. + */ + void setPlanner( PathPlanner * planner ) { _planner = planner; } + + /*! + * @brief Get the planner for the localizer. + * + * @returns A pointer to the planner + */ + PathPlanner * getPlanner() { return _planner; } + + /*! + * @brief Returns the occupant set for the given node + * + * @param nodeID The index of the desired node. + * @returns A pointer to the OccupantSet of the given node. + */ + const OccupantSet * getNodeOccupants( unsigned int nodeID ) const { return &_nodeOccupants[ nodeID ]; } + + /*! + * @brief Returns a const pointer to the underlying navigation mesh + * + * @returns The pointer to the navigation mesh. + */ + const NavMeshPtr getNavMesh() const { return _navMesh; } + + /*! + * @brief Returns a pointer to the underlying navigation mesh + * + * @returns The pointer to the navigation mesh. + */ + NavMeshPtr getNavMesh() { return _navMesh; } + + //////////////////////////////////////////////////////////////// + // Construction functions + //////////////////////////////////////////////////////////////// + + /*! + * @brief Parses a navigation mesh localizer definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a NavMeshLocalizer, but to a Resource. The + * ResourceManager uses it to load and instantiate NavMeshLocalizer instances. + * + * @param fileName The path to the file containing the NavMesh + * definition. + * @returns A pointer to the new NavMeshLocalizer (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + friend class PortalPath; + + protected: + /*! + * @brief The underlying navigation mesh to perform operations on. + */ + NavMeshPtr _navMesh; + + /*! + * @brief Determines if just the position of agents on paths is tracked + * (true) or the position of all agents (false). + */ + bool _trackAll; + + /*! + * @brief Optional planner. This is only non-NULL if there is a PathPlanner created either + * by a NavMeshGoalGenerator or NavMeshVelComponent. + */ + PathPlanner * _planner; + + /*! + * @brief A mapping from agent id to the agent's location w.r.t. the + * navigation mesh. + */ + // NOTE: In order to call the [] operator in a const function, this needs to + // be mutable. Even if the code guarantees no changes. + mutable HASH_MAP< size_t, NavMeshLocation > _locations; + + /*! + * @brief Lock for location map (_locations). + */ + ReadersWriterLock _locLock; + + /*! + * @brief A mapping from node id to agent ids, specifying the population + * of each agent. + */ + OccupantSet * _nodeOccupants; + + /*! + * @brief Determines which node an agent is in without previous knowledge + * + * @param p Given the initial position, returns the node + * this point lies on (with the highest elevation). + * @param tgtElev The target elevation for the agent. The default + * value leads to the highest node being selected. + * But giving an alternative value will change it to + * select a node nearest the current elevation. + * @returns The index of the node on which the point lies closest in elevation. + * to the tgtElev value. If the point does not lie on any mesh node, + * NavMeshLocation::NO_NODE is returned. + */ + unsigned int findNodeBlind( const Vector2 & p, float tgtElev=1e5f ) const; + + /*! + * @brief Determines if the point is in a neighboring node to the given node + * + * @param node The navigation mesh node whose neighbors + * need to be tested. + * @param p The point to test against the neighboring nodes. + * @returns The index of the neighboring node which contains p. If p + * does not lie on any neighboring mesh node, NavMeshLocation::NO_NODE + * is returned. + */ + unsigned int testNeighbors( const NavMeshNode & node, const Vector2 & p ) const; + }; + + + /*! + * @brief The definition of the managed pointer for NavMeshLocalizer data + */ + typedef ResourcePtr< NavMeshLocalizer > NavMeshLocalizerPtr; + + /*! + * @brief Loads the navigation mesh of the given name + * + * @param fileName The name of the file containing the navigation + * mesh definition. + * @param usePlanner Indicates if a planner is required (true) or not (false). + * @returns The NavMeshLocalizerPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ + NavMeshLocalizerPtr loadNavMeshLocalizer( const std::string & fileName, bool usePlanner ) throw ( ResourceException ); + +} // namespace Menge + +#endif // __NAV_MESH_LOCALIZER_H__ diff --git a/src/Menge/MengeCore/resources/NavMeshNode.cpp b/src/Menge/MengeCore/resources/NavMeshNode.cpp new file mode 100644 index 00000000..d09350e2 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshNode.cpp @@ -0,0 +1,180 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshNode.h" +#include "NavMeshEdge.h" +#include "NavMeshObstacle.h" +#include "Logger.h" +#include +#include + +namespace Menge { + + ////////////////////////////////////////////////////////////////////////////////////// + // Implementation of NavMeshNode + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode::NavMeshNode(): _edges(0x0), _edgeCount(0), _obstacles(0x0), _obstCount(0),_center(), _poly() { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode::~NavMeshNode() { + if ( _edges ) { + delete [] _edges; + } + if ( _obstacles ) { + delete [] _obstacles; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshNode & NavMeshNode::operator=( const NavMeshNode & n ) { + // Copy edges + // If I already have memory and it is too small, delete and create + if ( _edgeCount < n._edgeCount ) { + if ( _edgeCount > 0 ) delete [] _edges; + _edges = new NavMeshEdge*[ n._edgeCount ]; + } + + _edgeCount = n._edgeCount; + for ( unsigned int e = 0; e < _edgeCount; ++e ) { + _edges[e] = n._edges[e]; + } + + // Copy obstacles + if ( _obstCount < n._obstCount ) { + if ( _obstCount > 0 ) delete [] _edges; + _obstacles = new NavMeshObstacle*[ n._obstCount ]; + } + _obstCount = n._obstCount; + for ( unsigned int o = 0; o < _obstCount; ++o ) { + _obstacles[o] = n._obstacles[o]; + } + + _center = n._center; + _poly = n._poly; + _id = n._id; + return *this; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + const NavMeshNode * NavMeshNode::getNeighbor( size_t i ) const { + assert( i < _edgeCount && "Trying to access a neighbor with an invalid index" ); + return _edges[ i ]->getOtherByPtr( this ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshEdge * NavMeshNode::getConnection( unsigned int nodeID ) { + for ( size_t e = 0; e < _edgeCount; ++e ) { + NavMeshEdge * edge = _edges[ e ]; + NavMeshNode * neighbor = edge->getOtherByPtr( this ); + if ( neighbor->_id == nodeID ) { + return edge; + } + } + return 0x0; + } + + + ////////////////////////////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + // This disables a 64-bit compatibility warning - pushing a 32-bit value into a 64-bit value. + // This can cause problems with SIGN EXTENSION. + // In this case, I know the value in being put into the pointer slot is an unsigned + // int, so sign extension is not a problem. Plus, they never get interpreted as + // pointers. These indices are eventually mapped to REAL pointers. + #pragma warning( disable : 4312 ) + #endif + bool NavMeshNode::loadFromAscii( std::ifstream & f ) { + // center + float cx, cy; + if ( ( f >> cx >> cy ) ) { + _center.set( cx, cy ); + } else { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: Unable to read center of node.\n"; + return false; + } + + // polygon + if ( ! _poly.loadFromAscii( f ) ) { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: Badly formatted node polygon for node.\n"; + return false; + } + + // edges + if ( ! ( f >> _edgeCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: unable to read the edge count for a node.\n"; + return false; + } + _edges = new NavMeshEdge*[ _edgeCount ]; + for ( size_t e = 0; e < _edgeCount; ++e ) { + unsigned int eID; + if ( ! ( f >> eID ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: unable to read the " << (e + 1) << "th edge for a node.\n"; + return false; + } + // This is a cheat -- I'm storing the index now, to convert it to a pointer later. + _edges[ e ] = ( NavMeshEdge *)eID; + } + + // obstacles + if ( ! ( f >> _obstCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: unable to read the adjacent obstacle count.\n"; + return false; + } + _obstacles = new NavMeshObstacle*[ _obstCount ]; + for ( size_t o = 0; o < _obstCount; ++o ) { + unsigned int oID; + if ( ! ( f >> oID ) ) { + logger << Logger::ERR_MSG << "Error in parsing nav mesh: unable to read the " << (o + 1) << "th adjacent obstacle.\n"; + return false; + } + // This is a cheat -- I'm storing the index now, to convert it to a pointer later. + _obstacles[ o ] = ( NavMeshObstacle *)oID; + } + return true; + } + #ifdef _WIN32 + #pragma warning( default : 4312 ) + #endif +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMeshNode.h b/src/Menge/MengeCore/resources/NavMeshNode.h new file mode 100644 index 00000000..22d950a1 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshNode.h @@ -0,0 +1,284 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMeshNode.h + * @brief Defines the "node" of the adjacency graph in a navigation mesh. + * The node corresponds to a polygon in the mesh. + */ + +#ifndef __NAV_MESH_NODE_H__ +#define __NAV_MESH_NODE_H__ + +#include +#include "fsmCommon.h" +#include "NavMeshPoly.h" + +namespace Menge { + + // Forward declarations + class NavMesh; + class NavMeshEdge; + class PathPlanner; + class NavMeshObstacle; + + /*! + * @brief The navigation mesh adjacency graph node. It corresponds to + * a convex polygon in the navigation mesh. + */ + class NavMeshNode { + public: + /*! + * @brief Constructor + */ + NavMeshNode(); + + /*! + * @brief Destructor + */ + ~NavMeshNode(); + + /*! + * @brief Assignment operator + */ + NavMeshNode & operator=( const NavMeshNode & n ); + + /*! + * @brief Sets the node identifier. + * + * @param id The identifier to set this node to. + */ + void setID( unsigned int id ) { _id = id; } + + /*! + * @brief Retrive the identifier for this node. + */ + unsigned int getID() const { return _id; } + + /*! + * @brief Sets the node's center value. + * + * @param c The point value to set. + */ + inline void setCenter( const Vector2 & c ) { _center.set( c ); } + + /*! + * @brief Reports the center (centroid) of the node's polygon. + * + * @returns The position of the polygon's centroid. + */ + Vector2 getCenter() const { return _center; } + + /*! + * @brief Reports the center (centroid) of the node's polygon. + * + * @returns The position of the polygon's centroid. + */ + Vector3 getCenter3D() const { return Vector3( _center.x(), _poly.getElevation( _center ), _center.y() ); } + + /*! + * @brief Returns the number of vertices in the node's polygon. + * + * @returns The number of vertices in the polygon. + */ + size_t getVertexCount() const { return _poly._vertCount; } + + /*! + * @brief Sets this node's polygon to the given vertex array. + * The polygon can then evaluate its indices with respect to + * this array of vertex values. + * + * @param vertices An array of Vector2's defining the + * polygon vertices. + */ + void setVertices( const Vector2 * vertices ) { _poly._vertices = vertices; } + + /*! + * @brief Gets the index of the ith vertex in this node's polygon + * + * @param i The local index of the vertex in the node's polygon. + * @returns The global index in the navigation mesh of the ith vertex + * in this node's polygon. + */ + unsigned int getVertexID( size_t i ) const { return _poly._vertIDs[ i ]; } + + /*! + * @brief Returns the number of obstacles connected to this node. + * + * @returns The number of obtacles in on this node. + */ + size_t getObstacleCount() const { return _obstCount; } + + /*! + * @brief Returns a const pointer to the ith obstacle in the node. + * + * @param i The local index of the desired obstacle. + * @returns A const pointer to the ith obstacle. + */ + const NavMeshObstacle * getObstacle( size_t i ) const { return _obstacles[ i ]; } + + /*! + * @brief Returns a const pointer to the ith obstacle in the node. + * + * @param i The local index of the desired obstacle. + * @returns A pointer to the ith obstacle. + */ + NavMeshObstacle * getObstacle( size_t i ) { return _obstacles[ i ]; } + + /*! + * @brief Reports the number of nodes adjacent to this node. + */ + size_t getNeighborCount() const { return _edgeCount; } + + /*! + * @brief Returns a pointer to the ith neighbor. + * + * @param i The index of the neighboring node to retrieve. + * The index is defined in the range [0, N-1], where + * this node has N neighbors. + * @returns A pointer to the ith neighboring node. + */ + const NavMeshNode * getNeighbor( size_t i ) const; + + /*! + * @brief Reports the number of edges on the node. + * + * @returns The number of edges. + */ + size_t getEdgeCount() const { return _edgeCount; } + + /*! + * @brief Retrieves the ith edge connected to this node. + * + * @param i The local index of the desired edge. + * @returns A pointer to the ith edge. + */ + NavMeshEdge * getEdge( size_t i ) { return _edges[ i ]; } + + /*! + * @brief Retrieves a const pointer to the ith edge connected to this node. + * + * @param i The local index of the desired edge. + * @returns A pointer to the ith edge. + */ + const NavMeshEdge * getEdge( size_t i ) const { return _edges[ i ]; } + + /*! + * @brief Returns the pointer to the edge connecting this node + * with the node whose identifier is given. + * + * @param nodeID The id of the desired adjacent node. + * @returns The pointer to the edge connecting the two nodes. + * If the nodes are not connected, NULL is returned. + */ + NavMeshEdge * getConnection( unsigned nodeID ); + + /*! + * @brief Reports if the given point is inside the polygon + * + * @param point The point to test. + * @returns A boolean reporting if the point lies inside the polygon + * (true) or outside (false ). + * // TODO: What about the boundary? + */ + bool containsPoint( const Vector2 & point ) const { return _poly.containsPoint( point ); } + + /*! + * @brief Sets the node properties from a node definition + * in the given ascii file stream. + * + * @param f The input file stream. + * @returns A boolean indicating successful parsing (true) or failure + * (false). + */ + bool loadFromAscii( std::ifstream & f ); + + /*! + * @brief Computes the height based on this node's polygon + */ + inline float getElevation( const Vector2 & p ) const { return _poly.getElevation( p ); } + + /*! + * @brief Computes the gradient based on this node's polygon + */ + inline Vector2 getGradient() const { return _poly.getGradient(); } + + friend class NavMesh; + friend class NavMeshEdge; + friend class PathPlanner; + + protected: + /*! + * @brief An array of edges connecting to other nodes + */ + NavMeshEdge ** _edges; + + /*! + * @brief The number of edges connecting to this node. + */ + size_t _edgeCount; + + /*! + * @brief An array of obstacles connected to this node. + */ + NavMeshObstacle ** _obstacles; + + /*! + * @brief The number of obstacles connecting to this node. + */ + size_t _obstCount; + + /*! + * @brief The "position" of the node - used to compute distance + * between node and goal (A* heuristic) + */ + Vector2 _center; + + /*! + * @brief The polygon associated with this node + */ + NavMeshPoly _poly; + + /*! + * @brief The identifier of this node + */ + unsigned int _id; + }; +} // namespace Menge + +#endif // __NAV_MESH_NODE_H__ diff --git a/src/Menge/MengeCore/resources/NavMeshObstacle.cpp b/src/Menge/MengeCore/resources/NavMeshObstacle.cpp new file mode 100644 index 00000000..125df3fe --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshObstacle.cpp @@ -0,0 +1,94 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshObstacle.h" +#include "Logger.h" +#include +#include + +namespace Menge { + + /*! + * @brief The minimum width for an edge to be considered valid. + */ + const float MIN_EDGE_WIDTH = 0.00001f; + + unsigned int NavMeshObstacle::NO_NEIGHBOR_OBST = std::numeric_limits< unsigned int >::max(); + + //////////////////////////////////////////////////////////////// + // Implementation of NavMeshObstacle + //////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + // This disables a 64-bit compatibility warning - pushing a 32-bit value into a 64-bit value. + // This can cause problems with SIGN EXTENSION. + // In this case, I know the value in being put into the pointer slot is an unsigned + // int, so sign extension is not a problem. Plus, they never get interpreted as + // pointers. These indices are eventually mapped to REAL pointers. + #pragma warning( disable : 4312 ) + #endif + + bool NavMeshObstacle::loadFromAscii( std::ifstream & f, Vector2 * vertices ) { + size_t v0, v1, node; + int nextObst; + if ( ! ( f >> v0 >> v1 >> node >> nextObst ) ) { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: missing edge data.\n"; + return false; + } else { + _point.set( vertices[ v0 ] ); + Vector2 disp = vertices[ v1 ] - vertices[ v0 ]; + _length = abs( disp ); + if ( _length <= MIN_EDGE_WIDTH ) { + logger << Logger::ERR_MSG << "\tError in parsing nav mesh: obstacle is too narrow (length = " << _length << ").\n"; + return false; + } + _unitDir.set( disp / _length ); + // Stash indices as pointers + if ( nextObst >= 0 ) { + _nextObstacle = ( Obstacle * )nextObst; + } else { + _nextObstacle = ( Obstacle * )NO_NEIGHBOR_OBST; + } + _node = ( NavMeshNode * )node; + } + return true; + } + #ifdef _WIN32 + #pragma warning( default : 4312 ) + #endif +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMeshObstacle.h b/src/Menge/MengeCore/resources/NavMeshObstacle.h new file mode 100644 index 00000000..b77580e9 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshObstacle.h @@ -0,0 +1,105 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMeshObstacle.h + * @brief Specification for obstacles in a navigation mesh file. + */ + +#ifndef __NAV_MESH_OBSTACLE__ +#define __NAV_MESH_OBSTACLE__ + +#include "Obstacle.h" +#include + +namespace Menge { + + // FORWARD DECLARATIONS + class NavMeshNode; + class NavMesh; + + /*! + * @brief Specification of an obstacle. It is the same as a pedModel + * specification but includes a pointer to a node to which it is + * attached. + */ + class NavMeshObstacle : public Agents::Obstacle { + public: + /*! + * @brief The index value if the obstacle has no neighboring obstacle + */ + static unsigned int NO_NEIGHBOR_OBST; + + /*! + * @brief Constructor + */ + NavMeshObstacle(): Agents::Obstacle(), _node(0x0) {} + + /*! + * @brief Sets the obstacle properties from an obstacle definition + * in the given ascii file stream. + * + * @param f The input file stream. + * @param vertices The array of vertices into which the definition + * indexes. + * @returns A boolean indicating successful parsing (true) or failure + * (false). + */ + bool loadFromAscii( std::ifstream & f, Vector2 * vertices ); + + /*! + * @brief Retrieve the nav mesh node to which this obstacle is adjacent. + * + * @returns A pointer to the node. + */ + inline const NavMeshNode * getNode() const { return _node; } + + friend class NavMeshNode; + friend class NavMesh; + + protected: + /*! + * @brief A nav mesh node to which this obstacle is attached. + * It could be attached to multiple, but this is the node + * for which it serves as an edge. + */ + NavMeshNode * _node; + }; +} // namespace Menge + +#endif // __NAV_MESH_OBSTACLE__ \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/NavMeshPoly.cpp b/src/Menge/MengeCore/resources/NavMeshPoly.cpp new file mode 100644 index 00000000..7a9b2c35 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshPoly.cpp @@ -0,0 +1,247 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NavMeshPoly.h" +#include "Logger.h" + +namespace Menge { + + ////////////////////////////////////////////////////////////////////////////////////// + // Implementation of NavMeshPoly + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshPoly::NavMeshPoly(): _vertIDs(0x0), _vertCount(0), _A(0.f), _B(0.f), _C(0.f) { + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshPoly::~NavMeshPoly() { + if ( _vertIDs ) { + delete [] _vertIDs; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + NavMeshPoly & NavMeshPoly::operator=( const NavMeshPoly & p ) { + _vertCount = p._vertCount; + if ( _vertIDs ) delete [] _vertIDs; + _vertIDs = new unsigned int[ _vertCount ]; + memcpy( &_vertIDs[0], &p._vertIDs[0], _vertCount * sizeof( unsigned int ) ); + _vertices = p._vertices; + _A = p._A; + _B = p._B; + _C = p._C; + return *this; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshPoly::containsPoint( const Vector2 & point ) const { + // classic polygon test by counting intersections between polygon and a line segment + // connecting the point and some infinitely distant point (specifically, a point + // with the same y-value as point, but x = -infinity. + // An even number means the point is outside, odd means inside. + // Have to handle the special case where the segment intersects a vertex carefully + // (otherwise it accidentally gets counted twice.) + + const float X = point.x(); + const float Y = point.y(); + + // Test the bounding area + // TODO: Why is this commented out? + //if ( X < _minX || + // X > _maxX || + // Y < _minY || + // Y > _maxY ) return false; + int count = 0; // number of intersections + for ( size_t e = 0; e < _vertCount; ++e ) { + const Vector2 & p0 = _vertices[ _vertIDs[e] ]; + + if ( p0.y() == Y && p0.x() <= X ) { + // There is a special case here where the line passes through the point + // tangentially to the polygon (i.e. it doesn't cut into the polygon. + // + // a\ /b + // \ / + // c\/______x + // + // The line segment through the test point x intersects point c, but the + // line segment doesn't cut through the polygon. Counting this would be + // incorrect. + // + // The solution is to test points a and b and make sure they lie on opposite + // sides of the line through x. If they do, it counts + // + // However if the test point IS the vertex, then it DOES count. + if ( p0.x() == X ) { + // the point is in the polygon + // this is slightly fragile -- the point will register as inside any + // polygon built on this point. + // + // A similar problem exists if x lies on the boundary of the polygon -- both + // polygons will consider it to be "inside". + return true; + } else { + size_t prev = e == 0 ? (_vertCount - 1 ) : ( e - 1 ); + size_t next = e == ( _vertCount - 1 ) ? 0 : ( e + 1 ); + float pY = _vertices[ _vertIDs[ prev ] ].y(); + float nY = _vertices[ _vertIDs[ next ] ].y(); + // if both y-values lie on the same side of the line, it is incidental contact. + // Don't count the contact + // There can be problems with signed zero values. Otherwise, probably safe. + if ( ( pY > Y && nY > Y ) || ( pY < Y && nY < Y ) ) continue; + } + // If the line segment intersects the first point, count it and move on. + ++count; + continue; + } + + const size_t next = ( e + 1 ) % _vertCount; + const Vector2 & p1 = _vertices[ _vertIDs[ next ] ]; + // simple cases in which there can be no intersection + if ( ( p0.y() > Y && p1.y() >= Y ) || // polysegment above line + ( p0.y() < Y && p1.y() <= Y ) || // polysegment below line + ( p0.x() > X && p1.x() > X ) ) { // polysegment to right of test line + + continue; + } + // legitimate intersection test + // compute where, between y0 and y1, I'll find Y + float t = Y - p0.y(); + float x0 = p0.x(); + float dx = p1.x() - x0; + + t /= p1.y() - p0.y(); + float x = x0 + t * dx; + if ( x <= X ) { // this includes if (X,Y) lies on the line between the two vertices + ++count; + } + } + return (count & 0x1) == 1; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float NavMeshPoly::getElevation( const Vector2 & point ) const { + return _A * point.x() + _B * point.y() + _C; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshPoly::loadFromAscii( std::ifstream & f ) { + if ( !( f >> _vertCount ) ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- unable to determine number of vertices in polygon!" ; + return false; + } + if ( _vertIDs ) delete [] _vertIDs; + _vertIDs = new unsigned int[ _vertCount ]; + for ( size_t i = 0; i < _vertCount; ++i ) { + if ( ! ( f >> _vertIDs[ i ] ) ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- number of vertices does not match declared number!" ; + return false; + } + } + if ( ! ( f >> _A >> _B >> _C ) ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- malformed plane definition!" ; + return false; + } + + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool NavMeshPoly::loadFromBinary( std::ifstream & f ) { + // TODO: This can lead to problems. If the size of size_t changes, + // but the file spec doesn't, this will read the wrong amount of data. + unsigned int data; + f.read( (char*)&data, sizeof( int ) ); + _vertCount = static_cast< size_t >( data ); + if ( f.fail() ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- unable to determine number of vertices in polygon!" ; + return false; + } + if ( _vertIDs ) delete [] _vertIDs; + _vertIDs = new unsigned int[ _vertCount ]; + f.read( (char*)&_vertIDs[0], static_cast< std::streamsize >( _vertCount ) * sizeof( unsigned int ) ); + if ( f.fail() ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- number of vertices does not match declared number!" ; + return false; + } + const int FLOAT_COUNT = 3; + float fData[ FLOAT_COUNT ]; + f.read( (char*)&fData[0], FLOAT_COUNT * sizeof( float ) ); + if ( f.fail() ) { + logger << Logger::ERR_MSG << "Malformed navigation mesh polygon -- malformed plane definition!" ; + return false; + } + _A = fData[0]; + _B = fData[1]; + _C = fData[2]; + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMeshPoly::initialize( size_t vCount, unsigned int * ids, float A, float B, float C ) { + _vertCount = vCount; + if ( _vertIDs ) { + delete [] _vertIDs; + } + _vertIDs = new unsigned int[ vCount ]; + memcpy( _vertIDs, ids, sizeof( unsigned int ) * vCount ); + _A = A; + _B = B; + _C = C; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + void NavMeshPoly::setBB( const Vector2 *vertices ) { + _minX = _minY = 1e6f; + _maxX = _maxY = -_minX; + for ( size_t v = 0; v < _vertCount; ++v ) { + const Vector2 & p0 = vertices[ _vertIDs[v] ]; + if ( p0.x() < _minX ) _minX = p0.x(); + if ( p0.x() > _maxX ) _maxX = p0.x(); + if ( p0.y() < _minY ) _minY = p0.y(); + if ( p0.y() > _maxY ) _maxY = p0.y(); + } + } +} // namespace Menge diff --git a/src/Menge/MengeCore/resources/NavMeshPoly.h b/src/Menge/MengeCore/resources/NavMeshPoly.h new file mode 100644 index 00000000..bc0091d1 --- /dev/null +++ b/src/Menge/MengeCore/resources/NavMeshPoly.h @@ -0,0 +1,222 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NavMeshPoly.h + * @brief Defines the geometric, convex polygon for each navigation + * mesh node + */ + +#ifndef __NAV_MESH_POLY_H__ +#define __NAV_MESH_POLY_H__ + +#include "fsmCommon.h" +#include "string.h" +#include + +namespace Menge { + + // FORWARD DECLARATIONS + class NavMeshNode; + class NavMesh; + + /*! + * @brief The polygon used in each node of a navigation mesh graph + */ + class NavMeshPoly { + public: + /*! + * @brief Constructor + */ + NavMeshPoly(); + + /*! + * @brief Destructor + */ + ~NavMeshPoly(); + + /*! + * @brief Assignment operator + */ + NavMeshPoly & operator=( const NavMeshPoly & n ); + + /*! + * @brief Reports if the point lies inside the polygon. + * NOTE: This is limited to 2D polygons. + * + * @param point The point to test. + * @returns A boolean reporting if the point is inside (true) + * or outside (false) the polygon + * TODO: Figure out what I do w.r.t. boundaries. + */ + bool containsPoint( const Vector2 & point ) const; + + /*! + * @brief Computes the elevation of the polygon at the + * given point. + * + * @param point A point on the polygon to evaluate. + * The function does not test to see if the point + * lies inside the polygon. + * @returns The elevation of the polygon at the given point. + */ + float getElevation( const Vector2 & point ) const; + + /*! + * @brief Reports the gradient of the polygon. + * Because it is a plane, the gradient is constant at all positions. + * + * @returns The gradient of the plane. + */ + Vector2 getGradient() const { return Vector2( _A, _B ); } + + /*! + * @brief Sets the polygon properties from a polygon definition + * in the given ascii file stream. + * + * @param f The input file stream. + * @returns A boolean indicating successful parsing (true) or failure + * (false). + */ + bool loadFromAscii( std::ifstream & f ); + + /*! + * @brief Sets the polygon properties from a polygon definition + * in the given binary file stream. + * + * @param f The input file stream. + * @returns A boolean indicating successful parsing (true) or failure + * (false). + */ + bool loadFromBinary( std::ifstream & f ); + + /*! + * @brief Initialize the polygon with vertices and equation of plane + * + * @param vCount Number of vertices in the polygon. + * @param ids An array of index values into the global + * set of vertices in the navigation mesh. + * @param A The first coefficient of the planar equation: + * f( x, y ) = Ax + By + C + * @param B The second coefficient of the planar equation: + * f( x, y ) = Ax + By + C + * @param C The third coefficient of the planar equation: + * f( x, y ) = Ax + By + C + */ + void initialize( size_t vCount, unsigned int * ids, float A=0.f, float B=0.f, float C=0.f ); + + friend class NavMeshNode; + friend class NavMesh; + + protected: + /*! + * @brief An array of indices into the vertex list defining the + * polygon. The indices must be ordered such that the + * vertices are visited in a counter-clockwise order. + * + * TODO: These are unsigned ints because of the binary file format. It would + * be better to decouple the file format from the representation. + */ + unsigned int *_vertIDs; + + /*! + * @brief The number of vertices in the polygon. + */ + size_t _vertCount; + + /*! + * @brief A pointer to the mesh vertex information for performing + * geometric tests. + */ + const Vector2 * _vertices; + + // TODO: Replace the individual bounding box with a BVH outside of the + // polygon. And then change the "is inside" function assuming + // that BVH tests have already been done. + /*! + * @brief Minimum extent on the x-axis of the polygon. + */ + float _minX; + + /*! + * @brief Maximum extent on the x-axis of the polygon. + */ + float _maxX; + + /*! + * @brief Minimum extent on the y-axis of the polygon. + */ + float _minY; + + /*! + * @brief Maximum extent on the y-axis of the polygon. + */ + float _maxY; + + /*! + * @brief Compute the bounding box for this polygon. + * + * @param vertices The actucal vertices used for + * geometric queries. + */ + void setBB( const Vector2 * vertices ); + + /*! + * @brief The first coefficient of the planar equation: + * f( x, y ) = Ax + By + C + * Used to compute the elevation of the point on the polygon. + */ + float _A; + + /*! + * @brief The second coefficient of the planar equation: + * f( x, y ) = Ax + By + C + * Used to compute the elevation of the point on the polygon. + */ + float _B; + + /*! + * @brief The third coefficient of the planar equation: + * f( x, y ) = Ax + By + C + * Used to compute the elevation of the point on the polygon. + */ + float _C; + }; +} // namespace Menge + +#endif // __NAV_MESH_POLY_H__ diff --git a/src/Menge/MengeCore/resources/PathPlanner.cpp b/src/Menge/MengeCore/resources/PathPlanner.cpp new file mode 100644 index 00000000..191dae3d --- /dev/null +++ b/src/Menge/MengeCore/resources/PathPlanner.cpp @@ -0,0 +1,307 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PathPlanner.h" +#include "Route.h" +#include "NavMesh.h" +#include "MinHeap.h" +#include "NavMeshNode.h" +#include +#include +#include + +#ifdef _OPENMP +#include +#endif + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PathPlanner - HELPER + ///////////////////////////////////////////////////////////////////// + + /*! + * @brief Creates unique keys for a route based on start and end nodes. + * + * Mangles the start and end node identifiers into a RouteKey for + * using in the map. + * This limits the number of nodes in the navigation mesh to the + * size of size_t (on a 64-bit machine it is most likely 8 bytes which + * means it can support 4 billion nodes in the mesh. + * + * @param start ID of start node. + * @param end ID of end node. + * @returns A unique node key based on the start and end nodes. + */ + RouteKey makeRouteKey( unsigned int start, unsigned int end ) { + const int SHIFT = sizeof( size_t ) * 4; // this assumes 8-bit byte + const size_t MASK = (1 << SHIFT) - 1; + return ( (size_t)start << SHIFT ) | ( (size_t)end & MASK ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of PathPlanner + ///////////////////////////////////////////////////////////////////// + + PathPlanner::PathPlanner( NavMeshPtr ptr ):_navMesh(ptr), DATA_SIZE(0), STATE_SIZE(0), _HEAP(0x0), _DATA(0x0), _STATE(0x0) { + size_t nCount = _navMesh->getNodeCount(); + initHeapMemory( nCount ); + } + + ///////////////////////////////////////////////////////////////////// + + PathPlanner::~PathPlanner() { + initHeapMemory( 0 ); + } + + ///////////////////////////////////////////////////////////////////// + + PortalRoute * PathPlanner::getRoute( unsigned int startID, unsigned int endID, float minWidth ) { + RouteKey key = makeRouteKey( startID, endID ); + + PortalRoute * route = 0x0; + _routeLock.lockRead(); + PRouteMapItr itr = _routes.find( key ); + if ( itr != _routes.end() ) { + // test the routes to see if they are passable + PRouteListItr rItr = itr->second.begin(); + for ( ; rItr != itr->second.end(); ++rItr ) { + if ( (*rItr)->_maxWidth > minWidth ) { + if ( (*rItr)->_bestSmallest <= minWidth * 1.05f ) { + route = *rItr; + } + } + } + } + _routeLock.releaseRead(); + + // Compute a new path + if ( route == 0x0 ) { + return computeRoute( startID, endID, minWidth ); + } else { + return route; + } + } + + ///////////////////////////////////////////////////////////////////// + + PortalRoute * PathPlanner::computeRoute( unsigned int startID, unsigned int endID, float minWidth ) { + const size_t N = _navMesh->getNodeCount(); + #ifdef _OPENMP + // Assuming that threadNum \in [0, omp_get_max_threads() ) + const unsigned int threadNum = omp_get_thread_num(); + AStarMinHeap heap( _HEAP + threadNum * N, _DATA + threadNum * DATA_SIZE, _STATE + threadNum * STATE_SIZE, _PATH + threadNum * N, N ); + #else + + AStarMinHeap heap( _HEAP, _DATA, _STATE, _PATH, N ); + #endif + + const Vector2 goalPos( _navMesh->getNode( endID ).getCenter() ); + + heap.g( startID, 0 ); + heap.h( startID, computeH( startID, goalPos ) ); + heap.f( startID, heap.h( startID ) ); + heap.push( startID ); + + bool found = false; + while ( !heap.empty() ) { + unsigned int x = heap.pop(); + + //std::cout << "\tTesting node " << x << "\n"; + if ( x == endID ) { + found = true; + break; + } + + NavMeshNode & node = _navMesh->_nodes[ x ]; + //std::cout << "\t\tNeighbors:\n"; + for ( size_t e = 0; e < node._edgeCount; ++e ) { + NavMeshEdge * edge = node._edges[ e ]; + unsigned int y = edge->getOtherByID( x )->_id; + //std::cout << "\t\t\t" << y << "\n"; + if ( heap.isVisited( y ) ) continue; + float distance = edge->getNodeDistance( minWidth ); + if ( distance < 0.f ) continue; + float tempG = heap.g( x ) + distance; + //std::cout << "\t\t\t\ttemp G: " << tempG << ", old g = " << heap.g(y) << "\n"; + + bool isOld = true; + if ( ! heap.isInHeap( y ) ) { + heap.h( y, computeH( y, goalPos ) ); + isOld = false; + } + if ( tempG < heap.g( y ) ) { + heap.setReachedFrom( y, x ); + heap.g( y, tempG ); + heap.f( y, tempG + heap.h( y ) ); + //std::cout << "\t\t\t\tIMPROVED: g = " << heap.g(y) << ", f = " << heap.f(y) << "\n"; + //std::cout << "\t\t\t\t" << y << " came from " << x << "\n"; + } + if ( ! heap.isInHeap( y ) ) { + heap.push( y ); + //std::cout << "\t\t\t\tAdding to open with h = " << heap.h(y) << "\n"; + } + } + } + + // reconstruct the path + if ( !found ) { + std::stringstream ss; + ss << "Trying to find a path from " << startID << " to " << endID << ". A* finished without a route!"; + throw PathPlannerException( ss.str() ); + } + + // Create the list of nodes through which I must pass + std::list< unsigned int > path; + unsigned int curr = endID; + while ( curr != startID ) { + path.push_front( curr ); + curr = heap.getReachedFrom( curr ); + } + path.push_front( startID ); + + #ifdef _WIN32 + // Visual studio 2005 compiler is giving an erroneous warning + // It feels that: + // unsigned int prev = *itr; + // Is trying to cast a value of type size_t into a value of type unsigned int + // which, if true, would possibly lose data. However, this is simply incorrect, + // as the iterator is to a list of unsigned ints. + // + // Because the code is correct, this is the only way to silence the stupid warning. + #pragma warning( disable : 4267 ) + #endif + + // Now construct the path + std::list< unsigned int >::const_iterator itr = path.begin(); + unsigned int prev = *itr; + NavMeshNode * prevNode = &_navMesh->_nodes[ prev ]; + ++itr; + + PortalRoute * route = new PortalRoute( startID, endID ); + route->_bestSmallest = minWidth; + for ( ; itr != path.end(); ++itr ) { + unsigned int id = *itr; + NavMeshEdge * edge = prevNode->getConnection( id ); + route->appendWayPortal( edge, prevNode->getID() ); + prevNode = &_navMesh->_nodes[ id ]; + } + #ifdef _WIN32 + #pragma warning( default : 4267 ) + #endif + cacheRoute( startID, endID, route ); + return route; + } + + ///////////////////////////////////////////////////////////////////// + + void PathPlanner::initHeapMemory( size_t nodeCount ) { + int threadCount = 1; + #ifdef _OPENMP + logger << Logger::INFO_MSG << "OMP ENABLED!\n"; + threadCount = omp_get_max_threads(); + #endif + logger << Logger::INFO_MSG << "Caching A* data for " << threadCount << " threads\n"; + if ( _DATA ) { + delete [] _DATA; + _DATA = 0x0; + delete [] _STATE; + _STATE = 0x0; + delete [] _HEAP; + _HEAP = 0x0; + delete [] _PATH; + _PATH = 0x0; + } + + DATA_SIZE = 3 * nodeCount; // the number of floats per thread in _data + STATE_SIZE = 2 * nodeCount; // the number of bools, per thread, in _state; + if ( nodeCount ) { + _DATA = new float[ threadCount * DATA_SIZE ]; + _STATE = new bool[ threadCount * STATE_SIZE ]; + _HEAP = new unsigned int[ threadCount * nodeCount ]; + _PATH = new unsigned int[ threadCount * nodeCount ]; + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + + float PathPlanner::computeH( unsigned int node, const Vector2 & goal ) { + assert( node >= 0 && node < _navMesh->getNodeCount() && "Trying to compute h for invalid node id" ); + return abs( _navMesh->_nodes[ node ]._center - goal ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + PortalRoute * PathPlanner::cacheRoute( unsigned int startID, unsigned int endID, PortalRoute * route ) { + _routeLock.lockWrite(); + PortalRoute * result = route; + RouteKey key = makeRouteKey( startID, endID ); + PRouteMapItr mapItr = _routes.find( key ); + if ( mapItr == _routes.end() ) { + // there have been no routes connecting these two points -- it is optimal + _routes[ key ] = PRouteList(); + _routes[ key ].push_back( route ); + } else { + // I have already found routes - are they equivalent? + float w = route->_maxWidth; + PRouteList & routeList = mapItr->second; + PRouteListItr rItr = routeList.begin(); + for ( ; rItr != routeList.end(); ++rItr ) { + float rWidth = (*rItr)->_maxWidth; + if ( rWidth > w ) { + // The next width has the capacity to handle agents on this route + // It is assumed that it hasn't ever been shown optimal for this route's + // required clearance (otherwise, we would've simply used it. + // Test to see if it is the same route + if ( route->isEquivalent( (*rItr) ) ) { + result = *rItr; + assert( route->_bestSmallest < result->_bestSmallest && "Recomputed an equivalent path which was already shown to be sufficiently wide and optimal" ); + result->_bestSmallest = route->_bestSmallest; + } else { + routeList.insert( rItr, route ); + } + _routeLock.releaseWrite(); + return route; + } + } + routeList.push_back( route ); + } + _routeLock.releaseWrite(); + return route; + } +} // namespace Menge diff --git a/src/Menge/MengeCore/resources/PathPlanner.h b/src/Menge/MengeCore/resources/PathPlanner.h new file mode 100644 index 00000000..e49ded67 --- /dev/null +++ b/src/Menge/MengeCore/resources/PathPlanner.h @@ -0,0 +1,277 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file PathPlanner.h + * @brief Defines an entity for computing paths through a navigation mesh. + */ + +#ifndef __PATH_PLANNER_H__ +#define __PATH_PLANNER_H__ + +#include "mengeCommon.h" +#include "NavMesh.h" +#include "ReadersWriterLock.h" +#include +#include + +namespace Menge { + + /*! + * @brief Exception class for path planner. + */ + class MENGE_API PathPlannerException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + PathPlannerException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + PathPlannerException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal path planner exception. + */ + class MENGE_API PathPlannerFatalException : public PathPlannerException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + PathPlannerFatalException() : MengeException(), PathPlannerException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + PathPlannerFatalException( const std::string & s ): MengeException(s), PathPlannerException(), MengeFatalException() {} + }; + + // FORWARD DECLARATIONS + class PortalRoute; + class PathPlanner; + + /*! + * @brief Definition of the identifier of a Route. + */ + typedef size_t RouteKey; + + /*! + * @brief A list of PortalRoute pointers. + */ + typedef std::list< PortalRoute * > PRouteList; + + /*! + * @brief An iterator to a PRouteList. + */ + typedef PRouteList::iterator PRouteListItr; + + /*! + * @brief A const iterator to a PRouteList. + */ + typedef PRouteList::const_iterator PRouteListCItr; + + /*! + * @brief A mapping from RouteKey to PRouteList. + */ + typedef HASH_MAP< RouteKey, PRouteList > PRouteMap; + + /*! + * @brief An iterator to a PRouteMap. + */ + typedef PRouteMap::iterator PRouteMapItr; + + /*! + * @brief A const iterator to a PRouteMap. + */ + typedef PRouteMap::const_iterator PRouteMapCItr; + + /*! + * @brief Class for computing paths through a navigation mesh. + */ + class PathPlanner { + public: + /*! + * @brief Constructor. + * + * @param ptr A resource pointer to the nav mesh the + * planner uses. + */ + PathPlanner( NavMeshPtr ptr ); + + /*! + * @brief Destrutor. + */ + ~PathPlanner(); + + /*! + * @brief Returns a route between the two specified nodes. + * + * @param startID The index of the navigation mesh node at + * which the route starts. + * @param endID The index of the navigation mesh node at + * which the route ends. + * @param minWidth The minimum passable width required for the + * route. + * @returns A pointer to a PortalRoute from startID to endID with + * the required clearance. + */ + PortalRoute * getRoute( unsigned int startID, unsigned int endID, float minWidth ); + + protected: + /*! + * @brief Computes a route (and adds it to the cache) between start + * and end with the minimum clearance given. + * + * @param startID The index of the navigation mesh node at + * which the route starts. + * @param endID The index of the navigation mesh node at + * which the route ends. + * @param minWidth The minimum passable width required for the + * route. + * @returns A pointer to a PortalRoute from startID to endID with + * the required clearance. + */ + PortalRoute * computeRoute( unsigned int startID, unsigned int endID, float minWidth ); + + /*! + * @brief Compute's "h" for the A* algorithm. H is the estimate of the + * cost of a node to a goal point. In this case, simply Euclidian + * distance. + * + * @param node The estimated cost from the given node to the goal point. + * @param goal The goal point. + * @returns The h-value. + */ + float computeH( unsigned int node, const Vector2 & goal ); + + /*! + * @brief Cache the given route going from start to goal + * + * Caching the route saves the solution for an agent from startID to endID with the + * provided minimum width. This route may be identical to a route that was found for + * a larger agent. If the previous agent was sufficiently large, a recomputation was + * triggered in case there was a better path. However, it may be that this new path + * is the same as the old path. In this case, the two routes are merged and a pointer + * to the merged route is returned. If this route is uniquely superior, then pointer + * provided as input will be returned. + * + * @param startID The index of the start node. + * @param endID The index of the end node. + * @param route The route between them. + * @returns The equivalent route. + */ + PortalRoute * cacheRoute( unsigned int startID, unsigned int endID, PortalRoute * route ); + + /*! + * @brief A mapping from RouteKeys (a size_t) to to a list of routes. + * The list consists of routes between the points in the + * route key in INCREASING maximum width. (i.e. narrowest + * route to widest route.) + */ + PRouteMap _routes; + + /*! + * @brief Lock for securing _routes; + */ + ReadersWriterLock _routeLock; + + /*! + * @brief The navigation mesh for planning on. + */ + NavMeshPtr _navMesh; + + /*! + * @brief Initializes the heap memory + * + * @param nodeCount The number of nodes for which to initialize memory. + */ + void initHeapMemory( size_t nodeCount ); + + /*! + * @brief The size of a block of data used for COST in + * the A* algorithm (3N, N = number of nodes) + */ + size_t DATA_SIZE; + + /*! + * @brief The size of a block of data used for STATE in + * the A* algorithm (2N, N = number of nodes) + */ + size_t STATE_SIZE; + + /*! + * @brief The full set of data to serve as the heap + * There are N entries in a single heap + * and one heap per thread. + */ + unsigned int * _HEAP; + + /*! + * @brief The full set of data for reconstructing the path. + * For any given entry i, the value at i is the index of + * the node from which i was reached. There is one block + * per thread. + */ + unsigned int * _PATH; + + /*! + * @brief The block of data for tracking the f, g, and h data for nodes. + * (This is where DATA_SIZE = 3N comes from.) One block for + * each active thread. + * The first N values in a block are the f values, the next N are the g values, + * and the last set of N values are the h values. + */ + float * _DATA; + + /*! + * @brief Block of data for reportin node state (if its in a heap or if its + * no longer used for calculation. First N booleans are "in heap", second + * N are "finished". One block of 2N booleans per thread. + */ + bool * _STATE; + }; +} // namespace Menge + +#endif // __PATH_PLANNER_H__ diff --git a/src/Menge/MengeCore/resources/Portal.cpp b/src/Menge/MengeCore/resources/Portal.cpp new file mode 100644 index 00000000..40f68597 --- /dev/null +++ b/src/Menge/MengeCore/resources/Portal.cpp @@ -0,0 +1,134 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Portal.h" +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Portal + ///////////////////////////////////////////////////////////////////// + + Portal::Portal( float x0, float y0, float x1, float y1 ) { + set( x0, y0, x1, y1 ); + } + + ///////////////////////////////////////////////////////////////////// + + void Portal::set( float x0, float y0, float x1, float y1 ) { + _p0.set( x0, y0 ); + _p1.set( x1, y1 ); + _dir = _p1 - _p0; + _mag = abs( _dir ); + _dir /= _mag; + } + + ///////////////////////////////////////////////////////////////////// + + void Portal::set( const Vector2 & p0, const Vector2 & p1 ) { + _p0 = p0; + _p1 = p1; + _dir = _p1 - _p0; + _mag = abs( _dir ); + _dir /= _mag; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 Portal::nearestPoint( const Vector2 & pos, float radius ) { + assert( _mag > radius && "Agent's with radius bigger than the portal width can't pass through" ); + // Be smart about this + // If the position projects onto the portal, then simply find the closest point to the + // "effective" portal + // If the position lies to the left of p0 + // We simply rotate the direction from end point to test position by the appropriate + // angle. We do this as follows: + // d = || pos - p0 || + // dHat = || pos - p0 || / d + // l = sqrtf( d^2 - radius^2 ) + // cosTheta = r / d + // sinTheta = l / d + // gx = R * ( cosTheta * dHat.x + sinTheta * dHat.y ) + p0.x + // gy = R * ( cosTheta * dHat.y - sinTheta * dHat.x ) + p0.y + // If the position lies to the right of p0, it does the same computation, but with + // the opposite rotation + + // Does pos project onto the portal + Vector2 disp = pos - _p0; + float dp = disp * _dir; + float mag = _mag - radius; + if ( dp < radius || dp > mag ) { + if ( dp > mag ) { + disp = pos - _p1; + } + float d2 = absSq( disp ); + float R2 = radius * radius; + if ( R2 > d2 ) { + // Currently overlapping the the end point + if ( dp < radius ) { + return pos + _dir; + } else { + return pos - _dir; + } + } + float d = sqrtf( d2 ); + float l = sqrtf( d2 - R2 ); + float cTheta = radius / d; + float sTheta = l / d; + float x, y; + if ( dp < radius ) { + x = cTheta * disp.x() + sTheta * disp.y(); + y = cTheta * disp.y() - sTheta * disp.x(); + } else { + x = cTheta * disp.x() - sTheta * disp.y(); + y = cTheta * disp.y() + sTheta * disp.x(); + } + Vector2 goal( x, y ); + goal *= radius / d; + if ( dp < radius ) { + return goal + _p0; + } else { + return goal + _p1; + } + } else { + return _p0 + _dir * dp; + } + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/Portal.h b/src/Menge/MengeCore/resources/Portal.h new file mode 100644 index 00000000..c988c0c9 --- /dev/null +++ b/src/Menge/MengeCore/resources/Portal.h @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Portal.h + * @brief The definition of a portal - a line which spans a clear area + * between obstacles. + */ + +#ifndef __PORTAL_H__ +#define __PORTAL_H__ + +#include "mengeCommon.h" + +namespace Menge { + + /*! + * @brief A simple portal definition. + * + * A portal is simply a line segment - a region through which agents can pass. + */ + class Portal { + public: + /*! + * @brief Default constructor. + */ + Portal():_p0(0.f,0.f), _p1(0.f,0.f), _mag(0.f), _dir(1.f,0.f) {} + + /*! + * @brief Constructor specifying portal geometry. + * + * @param x0 The x-position of the first end point. + * @param y0 The y-position of the first end point. + * @param x1 The x-position of the second end point. + * @param y1 The y-position of the second end point. + */ + Portal( float x0, float y0, float x1, float y1 ); + + /*! + * @brief Sets the geometry of the portal + * + * @param x0 The x-position of the first end point. + * @param y0 The y-position of the first end point. + * @param x1 The x-position of the second end point. + * @param y1 The y-position of the second end point. + */ + void set( float x0, float y0, float x1, float y1 ); + + /*! + * @brief Sets the geometry of the portal + * + * @param p0 The position of the first end point. + * @param p1 The position of the second end point. + */ + void set( const Vector2 & p0, const Vector2 & p1 ); + + /*! + * @brief Computes the neareset *clearable* point w.r.t. the portal + * + * Given the position and radius of an agent, computes the best clearable goal point. + * Clearable means that the straight-line path between the agent's current position + * and that goal point does NOT intersect either end point of the goal. + * + * This is important because we assume that the end points attach to obstacles and + * if the end point intersects the path, that means the preferred velocity is + * leading the agent into a collision with the obstacle. + * + * @param pos The position of the agent. + * @param radius The radius of the agent. + * @returns The nearest *clearable* point. + */ + Vector2 nearestPoint( const Vector2 & pos, float radius ); + + /*! + * @brief The first end point of the portal line segment. + */ + Vector2 _p0; + + /*! + * @brief The second end point of the portal line segment. + */ + Vector2 _p1; + + /*! + * @brief The distance between endpoints (i.e., length of the portal). + */ + float _mag; + + /*! + * @brief The direction from the first to the second end point of the portal. + */ + Vector2 _dir; + }; +} // namespace Menge +#endif // __PORTAL_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/PortalPath.cpp b/src/Menge/MengeCore/resources/PortalPath.cpp new file mode 100644 index 00000000..9f3d9ffa --- /dev/null +++ b/src/Menge/MengeCore/resources/PortalPath.cpp @@ -0,0 +1,344 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "PortalPath.h" +#include "WayPortal.h" +#include "BaseAgent.h" +#include "PathPlanner.h" +#include "NavMeshLocalizer.h" +#include "Funnel.h" +#include "Goals/Goal.h" +#include "fsmCommon.h" +#include "Core.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PortalPath + ///////////////////////////////////////////////////////////////////// + + PortalPath::PortalPath( const Vector2 & startPos, const BFSM::Goal * goal, const PortalRoute * route, float agentRadius ): _route(route), _goal(goal), _currPortal(0), _waypoints(0x0), _headings(0x0) { + computeCrossing( startPos, agentRadius ); + } + + ///////////////////////////////////////////////////////////////////// + + PortalPath::~PortalPath() { + if ( _waypoints ) delete [] _waypoints; + if ( _headings ) delete [] _headings; + } + + ///////////////////////////////////////////////////////////////////// + + void PortalPath::setPreferredDirection( const Agents::BaseAgent * agent, float headingCos, Agents::PrefVelocity & pVel ) { + const size_t PORTAL_COUNT = _route->getPortalCount(); + Vector2 dir; + if ( _currPortal >= PORTAL_COUNT ) { + // assume that the path is clear + // TODO: See GoalVC + _goal->setDirections( agent->_pos, agent->_radius, pVel ); + + // speed + Vector2 goalPoint = pVel.getTarget(); + Vector2 disp = goalPoint - agent->_pos; + const float distSq = absSq( disp ); + float speed = agent->_prefSpeed; + + if ( distSq <= 0.0001f ) { + // I've basically arrived -- speed should be zero. + speed = 0.f; + } else { + const float speedSq = speed * speed; + const float TS_SQD = SIM_TIME_STEP * SIM_TIME_STEP; + if ( distSq / speedSq < TS_SQD ) { + // The distance is less than I would travel in a single time step. + speed = sqrtf( distSq ) / SIM_TIME_STEP; + } + } + pVel.setSpeed( speed ); + } else { + const WayPortal * portal = _route->getPortal( _currPortal ); + Vector2 goalDir( _waypoints[ _currPortal ] - agent->_pos ); + float dist = abs( goalDir ); + // If the displacement to the next way point is large enough + // (i.e., not essentially zero), use it, otherwise, peek + // into the next waypoint. + // + // The goal is to always provide a goalDir to the portal + // that is well-defined and unit-length. + bool bigEnough = dist >= EPS; + if ( bigEnough ) { + goalDir /= dist; + if ( goalDir * _headings[ _currPortal ] < headingCos ) { + // Heading has deviated too far recompute crossing + FunnelPlanner planner; + planner.computeCrossing( agent->_radius, agent->_pos, this, _currPortal ); + goalDir = _waypoints[ _currPortal ] - agent->_pos; + dist = abs( goalDir ); + if ( bigEnough = ( dist >= EPS ) ) { + goalDir /= dist; + } + } + } + if ( ! bigEnough ) { + // simply cross the wayportal perpendicularly + //goalDir.set( portal->getCrossingDir( agent->_pos ) ); + if ( _currPortal + 1 < getPortalCount() ) { + // calculate w.r.t. next waypoint + goalDir = norm( _waypoints[ _currPortal + 1 ] - agent->_pos ); + } else { + // calculate w.r.t. goal + Vector2 gp; + _goal->getTargetPoint( gp, agent->_radius ); + goalDir = norm( gp - agent->_pos ); + } + } + assert( abs( goalDir ) > EPS && "Providing a goal direction that is too small" ); + + pVel.setTarget( _waypoints[ _currPortal ] ); + portal->setPreferredDirection( agent->_pos, agent->_radius, goalDir, pVel ); + } + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int PortalPath::updateLocation( const Agents::BaseAgent * agent, const NavMeshPtr & navMesh, const NavMeshLocalizer * localizer, PathPlanner * planner ) { + // If off path, replan get a new route + // TODO: If off "approach" vector, recompute crossing + bool changed = false; + unsigned int currNodeID = getNode(); + const NavMeshNode * currNode = &(navMesh->getNode( currNodeID ) ); + // test current location + const Vector2 & p = agent->_pos; + + const unsigned int PORTAL_COUNT = static_cast< unsigned int >( _route->getPortalCount() ); + if ( ! currNode->containsPoint( p ) ) { + // test to see if I've progressed to the next + + bool gotoNext = false; + const NavMeshNode * nextNode = 0x0; + if ( _currPortal + 1 < PORTAL_COUNT ) { + // there is another way portal to test + const WayPortal * nextPortal = _route->getPortal( _currPortal + 1 ); + size_t nextID = nextPortal->_nodeID; + nextNode = &(navMesh->getNode( (unsigned int) nextID ) ); + gotoNext = nextNode->containsPoint( p ); + } else if ( _currPortal < PORTAL_COUNT ) { + // the next node is the goal polygon + nextNode = &(navMesh->getNode( (unsigned int) _route->getEndNode() ) ); + gotoNext = nextNode->containsPoint( p ); + } + if ( gotoNext ) { + // I've made progress, simply advance + ++_currPortal; + assert( _currPortal <= PORTAL_COUNT && "Incremented current portal larger than goal" ); + changed = true; + } + else { + const NavMeshNode * prevNode = 0x0; + // test to see if I've gone backwards + bool gotoPrev = false; + if ( _currPortal > 0 ) { + const WayPortal * prevPortal = _route->getPortal( _currPortal - 1 ); + size_t prevID = prevPortal->_nodeID; + prevNode = &(navMesh->getNode( (unsigned int) prevID ) ); + gotoPrev = prevNode->containsPoint( p ); + } + if ( gotoPrev ) { + // back up to previous way portal in path + --_currPortal; + changed = true; + } else { + // Agent is not in current, previous or next polygons - agent got + // pushed off path - find a new path + // Path needs the nav mesh + // Assume that I must be in a neighboring node (the alternative is + // catstrophic) + // search current node's neighbors that aren't previous and aren't next + const size_t NBR_COUNT = currNode->getNeighborCount(); + for ( size_t n = 0; n < NBR_COUNT; ++n ) { + const NavMeshNode * node = currNode->getNeighbor( n ); + if ( node == nextNode || node == prevNode ) continue; + if ( node->containsPoint( p ) ) { + // find a new path from this node to the goal + replan( p, node->getID(), _route->getEndNode(), agent->_radius, planner ); + changed = true; + } + } + + // It is possible for the agent, in some cases, to advance several nodes in a single time step + // (e.g., when the navigation mesh has many long, skinny triangles and the agent steps across the + // narrow fan). + // In this case, the agent should search forwards along the path before blindly searching. + + // TODO: + // If it gets "lost" at the beginning of a long path, I'm doing a bunch of wasted testing. + // Given how far the agent is from a particular portal, I know I should probably stop + // looking as the portals are only going to get farther. So, that means the inside + // query should CHEAPLY compute some sense of distance to the polygon so I can drop + // out. + if ( changed == false ) { + size_t testPortal = _currPortal + 2; + while ( testPortal < PORTAL_COUNT ) { + const WayPortal * nextPortal = _route->getPortal( testPortal ); + size_t testID = nextPortal->_nodeID; + const NavMeshNode * testNode = &(navMesh->getNode( (unsigned int) testID ) ); + if ( testNode->containsPoint( p ) ) { + _currPortal = testPortal; + changed = true; + break; + } + ++testPortal; + } + } + if ( changed == false ) { + // I exited the loop without finding an intermediate node -- test the goal node + const NavMeshNode * testNode = &(navMesh->getNode( (unsigned int) _route->getEndNode() ) ); + if ( testNode->containsPoint( p ) ) { + _currPortal = PORTAL_COUNT; + changed = true; + } + } + + if ( !changed ) { + #ifdef _DEBUG + logger << Logger::WARN_MSG << "Agent " << agent->_id << " got pushed from its goal into a non-adjacent goal!!\n"; + #endif + // do a full find path searching for the agent position + float lastElevation = currNode->getElevation( p ); + unsigned int nodeID = localizer->findNodeBlind( p, lastElevation ); + if ( nodeID != NavMeshLocation::NO_NODE ) { + try { + replan( p, nodeID, _route->getEndNode(), agent->_radius, planner ); + } catch ( PathPlannerException ) { + std::stringstream ss; + ss << "Agent " << agent->_id << " trying to find a path from " << nodeID << " to " << _route->getEndNode() << ". A* finished without a route!"; + throw PathPlannerException( ss.str() ); + } + } + changed = true; + } + } + } + } + /* + // TODO: Implement the idea of replanning the path based on getting pushed off + // approach vector + if ( !changed && _currPortal < _route->getPortalCount() ) { + // vector from crossing point to current position. + // examine angle between original approach vector and current approach vector. + // If the angle > some threshold, replan. + } + */ + if ( _currPortal < _route->getPortalCount() ) { + return _route->getPortal( _currPortal )->_nodeID; + } else { + return _route->getEndNode(); + } + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int PortalPath::getNode() const { + if ( _currPortal == _route->getPortalCount() ) { + return _route->getEndNode(); + } else { + return _route->getPortalNode( _currPortal ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void PortalPath::computeCrossing( const Vector2 & startPos, float agentRadius ) { + const size_t PORTAL_COUNT = _route->getPortalCount(); + if ( PORTAL_COUNT > 0 ) { + assert( _waypoints == 0x0 && "Computing the crossing for a path that already exists" ); + _currPortal = 0; + _waypoints = new Vector2[ PORTAL_COUNT ]; + _headings = new Vector2[ PORTAL_COUNT ]; + FunnelPlanner planner; + planner.computeCrossing( agentRadius, startPos, this ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void PortalPath::replan( const Vector2 & startPos, unsigned int startNode, unsigned int endNode, float agentRadius, PathPlanner * planner ) { + PortalRoute * route = planner->getRoute( startNode, _route->getEndNode(), agentRadius * 2.f ); + if ( _waypoints != 0x0 ) { + delete [] _waypoints; + _waypoints = 0x0; + delete [] _headings; + _headings = 0x0; + } + _currPortal = 0; + _route = route; + computeCrossing( startPos, agentRadius ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 PortalPath::getWayPoint(size_t i) const { + const size_t PORTAL_COUNT = _route->getPortalCount(); + assert( i >= 0 && i < PORTAL_COUNT && "Invalid index into the path!" ); + return _waypoints[ i ]; + } + + ///////////////////////////////////////////////////////////////////// + + unsigned int PortalPath::getNode( size_t i ) const { + const size_t PORTAL_COUNT = _route->getPortalCount(); + assert( i >= 0 && i <= PORTAL_COUNT && "Invalid index into the path!" ); + if ( i < PORTAL_COUNT ) { + return _route->getPortalNode( i ); + } else { + return _route->getEndNode(); + } + } + + ///////////////////////////////////////////////////////////////////// + + void PortalPath::setWaypoints( size_t start, size_t end, const Vector2 & p0, const Vector2 & dir ) { + for ( size_t i = start; i < end; ++i ) { + _waypoints[ i ].set( _route->getPortal( i )->intersectionPoint( p0, dir ) ); + //_waypoints[ i ].set( p0 ); + _headings[ i ].set( dir ); + } + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/PortalPath.h b/src/Menge/MengeCore/resources/PortalPath.h new file mode 100644 index 00000000..c61b207e --- /dev/null +++ b/src/Menge/MengeCore/resources/PortalPath.h @@ -0,0 +1,245 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __PORTAL_PATH_H__ +#define __PORTAL_PATH_H__ + +/*! + * @file PortalPath.h + * @brief The definition of a path through a navigation mesh. + * Each leg of the path is defined by a portal (the width of a shared + * edge.) + */ + +#include "mengeCommon.h" +#include "Route.h" +#include "NavMesh.h" +#include "Goals/Goal.h" + + +namespace Menge { + + // Forward Declaration + class NavMeshLocalizer; + class PathPlanner; + namespace Agents { + class BaseAgent; + } + + /*! + * @brief The definition of a path through space comprising of a sequence of portals. + * + * The path is repsonsible for computing instantaneous preferred velocity for an agent + * based on a PortalRoute and an optimized path through the portals. + */ + class PortalPath { + public: + /*! + * @brief Constructor + * + * @param startPos The 2D position where the path starts + * @param goal The goal (whose centroid lies in the final polygon). + * @param route The route the path follows + * @param agentRadius The radius of the given agent. + */ + PortalPath( const Vector2 & startPos, const BFSM::Goal * goal, const PortalRoute * route, float agentRadius ); + + /*! + * @brief Destructor + */ + ~PortalPath(); + + /*! + * @brief Sets the directions in the preferred velocity from the path + * + * @param agent The agent for which the preferred direction should be computed. + * @param headingCos The cosine of the maximum allowable angular deviation + * of heading (between planned and realized) before a + * new funnel algorithm is triggered to improve the path. + * @param pVel The preferred velocity whose directions are to be set. + */ + void setPreferredDirection( const Agents::BaseAgent * agent, float headingCos, Agents::PrefVelocity & pVel ); + + /*! + * @brief Updates the location of the agent relative to the nav mesh. + * + * @param agent The agent whose location is updated. + * @param navMesh The navmesh for making queries. + * @param localizer The nav mesh localizer for identifying locations. + * @param planner The nav mesh path planner for creating new routes. + * @returns The index of the node the agent is in. + */ + unsigned int updateLocation( const Agents::BaseAgent * agent, const NavMeshPtr & navMesh, const NavMeshLocalizer * localizer, PathPlanner * planner ); + + /*! + * @brief Reports the node the agent is currently in. + * + * @returns The index of the node associated with this location. + * If the location is not on a node, PortalPath::NO_NODE is returned. + */ + unsigned int getNode() const; + + /*! + * @brief Reports the number of way points in the path (*not* including the goal) + * + * @return The number of points (*not* including the goal). + */ + inline size_t getWayPointCount() const { return _route->getPortalCount(); } + + /*! + * @brief Returns the position of the ith way point. + * + * @param i The index of the desired way point. + * @returns The 2d position of the desired way point. + */ + Vector2 getWayPoint( size_t i ) const; + + /*! + * @brief Returns the goal. + * + * @returns The goal. + */ + inline const BFSM::Goal * getGoal() const { return _goal; } + + /*! + * @brief Returns the centroid of the goal. + * + * @returns The goal's centroid. + */ + inline Vector2 getGoalCentroid() const { return _goal->getCentroid(); } + + /*! + * @brief Returns the identifier for the destination node on the path. + * + * @returns The destination node's index. + */ + inline unsigned int getEndNode() const { return _route->getEndNode(); } + + /*! + * @brief Returns the id of the node traveled for the ith way point. + * + * @param i The index of the ith way point. + * @returns The identifier of the node the agent would be travelling on + * while making progress toward the ith point. + */ + unsigned int getNode( size_t i ) const; + + /*! + * @brief Returns the index of the current portal (the portal + * the agent is currently headed towards. + * + * @returns The index of the current portal. + */ + inline size_t getCurrentPortal() const { return _currPortal; } + + /*! + * @brief Reports the number of portals in the path) + * + * @return The number of portals. + */ + inline size_t getPortalCount() const { return _route->getPortalCount(); } + + /*! + * @brief Returns the ith portal + * + * @param i The index of the desired portal + * @returns A pointer to the ith portal. + */ + inline const WayPortal * getPortal( size_t i ) const { return _route->getPortal( i ); } + + /*! + * @brief Set the waypoints for all of the indicated way portals. + * + * @param start The index of the first portal to set the crossing point. + * @param end The index of the first portal to stop at. In other words, + * portals in the open interval [start, end) will receive + * crossing values. end will not be included. + * @param p0 The way point. + * @param dir The expected direction toward the way point along the path. + */ + void setWaypoints( size_t start, size_t end, const Vector2 & p0, const Vector2 & dir ); + + protected: + /*! + * @brief The route to follow. + */ + const PortalRoute * _route; + + /*! + * @brief The ultimate goal. + */ + const BFSM::Goal * _goal; + + /*! + * @brief The index of the way portal currently serving as + * immediate goal. -1 means it's at the end. + */ + size_t _currPortal; + + /*! + * @brief Computes the crossing values for each portal + * + * @param startPos The 2D position where the path starts + * @param agentRadius The radius of the given agent. + */ + void computeCrossing( const Vector2 & startPos, float agentRadius ); + + /*! + * @brief The sequence of way points. Some way points will be duplicated. + */ + Vector2 * _waypoints; + + /*! + * @brief The original direction to the way point. + */ + Vector2 * _headings; + + /*! + * @brief Something has changed and the path has to replan. + * + * @param startPos The starting position. + * @param startNode The starting node (startPos should lie on this node.) + * @param endNode The ending node. + * @param minWidth The minimum width required for clearance. + * @param planner The planner. + * ?? Extra stuff to do the funnel computation. + */ + void replan( const Vector2 & startPos, unsigned int startNode, unsigned int endNode, float minWidth, PathPlanner * planner ); + }; +} // namespace Menge +#endif // __PORTAL_PATH_H__ diff --git a/src/Menge/MengeCore/resources/Resource.cpp b/src/Menge/MengeCore/resources/Resource.cpp new file mode 100644 index 00000000..710d51cb --- /dev/null +++ b/src/Menge/MengeCore/resources/Resource.cpp @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Resource.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of Resource + ///////////////////////////////////////////////////////////////////// + + void Resource::destroy() { + delete this; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/Resource.h b/src/Menge/MengeCore/resources/Resource.h new file mode 100644 index 00000000..167c52d1 --- /dev/null +++ b/src/Menge/MengeCore/resources/Resource.h @@ -0,0 +1,277 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Resource.h + * @brief The basic class for all on-disk resources. + */ + +#ifndef __RESOURCE_H__ +#define __RESOURCE_H__ + +#include "CoreConfig.h" +#include "ResourceManager.h" +#include "SimpleLock.h" +#include "MengeException.h" +#include + +namespace Menge { + + /*! + * @brief A base exception for resources to throw. + */ + class MENGE_API ResourceException : public virtual MengeException { + public: + /*! + * @brief Default constructor. + */ + ResourceException() : MengeException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ResourceException( const std::string & s ): MengeException(s) {} + }; + + /*! + * @brief The fatal resource exception. + */ + class MENGE_API ResourceFatalException : public ResourceException, public MengeFatalException { + public: + /*! + * @brief Default constructor. + */ + ResourceFatalException() : MengeException(), ResourceException(), MengeFatalException() {} + + /*! + * @brief Constructor with message. + * + * @param s The exception-specific message. + */ + ResourceFatalException( const std::string & s ): MengeException(s), ResourceException(), MengeFatalException() {} + }; + + /*! + * @brief Basic class for managing on-disk resources. + * + * This is for data structures that are defined in files but may be used + * by multiple entities. This prevents unnecessary loading and duplication + * and allows for centralized memory management. + */ + class MENGE_API Resource { + public: + /*! + * @brief Constructor. + * + * This does not initialize the data structure. It merely registers the resource. + * + * @param fileName The path to the on-disk resource. + */ + Resource( const std::string & fileName ):_fileName(fileName), _refCount(0) {} + + /*! + * @brief This supplants the destructor. + * + * In order to preserve potential problems in windows when + * dlls do not share the same c-runtime library, the destructor + * is held to be private. To garbage collect a Resource, + * the destroy method should be called (which in turn, will call + * the destructor from its own memory space, averting run-time + * crashes). + * + * Once this has been called, the Resource no longer exists. Calling + * methods or accessing members will produce indetermine behavior + * (most likely errors). + */ + void destroy(); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~Resource() {} + + public: + /*! + * @brief Return the file name for this resource. + * + * @returns The file name associated with this resource. + */ + const std::string & getName() const { return _fileName; } + + /*! + * @brief Increment references to the managed data. + * + * Any object that carries a pointer to managed data should call this function + * when acquiring and storing a pointer to that data. + * + * @returns The total number of references. + */ + int incRef() { _lock.lock(); int val = ++_refCount; _lock.release(); return val; } + + /*! + * @brief Decrement references to the managed data. + * + * Any object that carries a pointer to managed data should call this function + * upon destruction (thereby removing its reference from the managed data's reference + * count. + * + * @returns The number of remaining references. + */ + int decRef() { _lock.lock(); int val = --_refCount; _lock.release(); return val; } + + /*! + * @brief Reports if the data is referenced. + * + * Any object that carries a pointer to managed data, after dereferencing itself + * upon destruction, should determine if it is no longer referenced and delete + * the object if this function returns true. NOTE: this is not thread-safe. + * + * @returns True if the underlying managed data is no longer referenced, false + * otherwise. + */ + bool isUnreferenced() const { _lock.lock(); bool val = _refCount <= 0; _lock.release(); return val; } + + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const = 0; + + friend class ResourceManager; + protected: + /*! + * @brief The file which contains the resource's data. + */ + const std::string _fileName; + + /*! + * @brief The number of data wrappers using this managed data. + */ + int _refCount; + + /*! + * @brief Simple lock to handle reference counts safely. + */ + SimpleLock _lock; + }; + + /*! + * @brief Base Class providing a pointer interface to Resources + */ + template < class Rsrc > + class ResourcePtr { + public: + /*! + * @brief Constructor. + * + * @param rsrc A pointer to the underlying data + */ + ResourcePtr( Rsrc * rsrc=0x0 ):_data(rsrc) { + if ( _data ) _data->incRef(); + } + + /*! + * @brief Copy constructor. + * + * @param rPtr A resource pointer to the underlying data. + */ + ResourcePtr( const ResourcePtr< Rsrc > & rPtr ):_data(rPtr._data) { + if ( _data ) _data->incRef(); + } + + /*! + * @brief Destructor + */ + ~ResourcePtr() { + if ( _data ) { + _data->decRef(); + if ( _data->isUnreferenced() ) { + ResourceManager::removeResource( _data ); + } + } + } + + /*! + * @brief Assignment operator + * + * @param ptr A resource pointer to the underlying data. + * @returns this object, having replaced + */ + ResourcePtr< Rsrc > & operator=( const ResourcePtr< Rsrc > & ptr ) { + if ( this != &ptr ) { + if ( _data ) { + _data->decRef(); + if ( _data->isUnreferenced() ) ResourceManager::removeResource( _data ); + } + _data = ptr._data; + if ( _data ) _data->incRef(); + } + return *this; + } + + /*! + * @brief The indirection operator. + * + * @returns Returns a pointer to the underlying data + */ + Rsrc * operator->() const { return _data; } + + /*! + * @brief Reports if to Resource pointers (of the same type) refer + * to the same data. + * + * @param ptr A pointer of the same type. + * @returns True if the underlying data is the same in each pointer + */ + bool operator==( const ResourcePtr< Rsrc > & ptr ) const { + return _data == ptr._data; + } + + protected: + /*! + * @brief The underlying resource data. + */ + Rsrc * _data; + }; +} // + +#endif // __RESOURCE_H__ diff --git a/src/Menge/MengeCore/resources/ResourceManager.cpp b/src/Menge/MengeCore/resources/ResourceManager.cpp new file mode 100644 index 00000000..59fa5047 --- /dev/null +++ b/src/Menge/MengeCore/resources/ResourceManager.cpp @@ -0,0 +1,106 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ResourceManager.h" +#include "Resource.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of ResourceManager + ///////////////////////////////////////////////////////////////////// + + ResourceMap ResourceManager::_resources; + const std::string ResourceManager::CAT_SYMBOL("|"); + + ///////////////////////////////////////////////////////////////////// + + Resource * ResourceManager::getResource( const std::string & fileName, Resource * (*reader)(const std::string & ), const std::string & suffix ) { + Resource * rsrc = 0x0; + const std::string key = fileName + CAT_SYMBOL + suffix; + ResourceMap::iterator itr = _resources.find( key ); + if ( itr != _resources.end() ) { + rsrc = itr->second; + } else { + rsrc = reader( fileName ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "Error loading the resource from: " << fileName << "\n"; + } + _resources[ key ] = rsrc; + } + + return rsrc; + } + + ///////////////////////////////////////////////////////////////////// + + void ResourceManager::cleanup() { + ResourceMap::iterator itr = _resources.begin(); + while ( itr != _resources.end() ) { + Resource * rsrc = itr->second; + if ( rsrc->isUnreferenced() ) { + rsrc->destroy(); + ResourceMap::iterator next = itr; + ++next; + _resources.erase( itr ); + itr = next; + } else { + ++itr; + } + } + } + + ///////////////////////////////////////////////////////////////////// + + bool ResourceManager::removeResource( Resource * rsrc ) { + const std::string key = rsrc->_fileName + CAT_SYMBOL + rsrc->getLabel(); + ResourceMap::iterator itr = _resources.find( key ); + if ( itr == _resources.end() ) { + logger << Logger::ERR_MSG << "Trying to remove a resource that the ResourceManager doesn't own: " << rsrc->_fileName << "\n"; + return false; + } + if ( ! rsrc->isUnreferenced() ) { + logger << Logger::ERR_MSG << "Trying to remove a resource with a non-zero reference count: " << rsrc->_fileName << "\n"; + return false; + } + _resources.erase( itr ); + rsrc->destroy(); + return true; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/ResourceManager.h b/src/Menge/MengeCore/resources/ResourceManager.h new file mode 100644 index 00000000..898aaf56 --- /dev/null +++ b/src/Menge/MengeCore/resources/ResourceManager.h @@ -0,0 +1,112 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ResourceManager.h + * @brief The basic class for all on-disk resources. + */ + +#ifndef __RESOURCE_MANAGER_H__ +#define __RESOURCE_MANAGER_H__ + +#include +#include +#include "mengeCommon.h" + +namespace Menge { + + // Forward declaration + class Resource; + + /*! + * @brief Type declaration for a resource map - mapping file names to resource pointers. + */ + typedef std::map< std::string, Resource * > ResourceMap; + + /*! + * @brief Class to handle management of on-disk resources. + */ + class MENGE_API ResourceManager { + public: + /*! + * @brief Retrieve a resource from the manager. + * + * @param fileName The name of the file associated with the resource. + * @param reader Pointer to a function for parsing the given file and + * producing a resource instance. + * @param suffix The string to append to the file name. This allows different + * *types* of resources basedon on the same file resource to + * be distinguished. It is the burden of the programmer to + * make sure each type provides a unique suffix, otherwise + * problems will arise between suffix collisions. + * @returns A pointer to the reference, if it is loaded, NULL otherwise. + * The caller is responsible for knowing what type of resource it + * should be and test it using a dynamic-cast. + */ + static Resource * getResource( const std::string & fileName, Resource * (*reader)(const std::string & ), const std::string & suffix ); + + /*! + * @brief Passes through the resources and removes all unreferenced resources. + */ + static void cleanup(); + + /*! + * @brief Remove the given resource + * + * @param rsrc A pointer to the resource to remove. + * @returns True if the pointer is successfully removed, false otherwise. + * It can fail if the resource doesn't belong to the manager or + * if the resources reference count is not zero. + */ + static bool removeResource( Resource * rsrc ); + + protected: + /*! + * @brief Mapping from resource name to resource. + */ + static ResourceMap _resources; + + private: + /*! + * @brief The string used to concatenate filenames with + * resource type suffixes. + */ + static const std::string CAT_SYMBOL; + }; +} // namespace Menge +#endif // __RESOURCE_MANAGER_H__ diff --git a/src/Menge/MengeCore/resources/RoadMapPath.cpp b/src/Menge/MengeCore/resources/RoadMapPath.cpp new file mode 100644 index 00000000..1a2a91b5 --- /dev/null +++ b/src/Menge/MengeCore/resources/RoadMapPath.cpp @@ -0,0 +1,132 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "RoadMapPath.h" +#include "BaseAgent.h" +#include "PrefVelocity.h" +#include "Core.h" +#include "SpatialQueries/SpatialQuery.h" +#include "Goals/Goal.h" +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of RoadMapPath + ///////////////////////////////////////////////////////////////////// + + RoadMapPath::RoadMapPath( size_t pointCount ): _targetID(0), _goal(0x0), _validPos(), _wayPointCount(pointCount) { + _wayPoints = new Vector2[ pointCount ]; + } + + ///////////////////////////////////////////////////////////////////// + + RoadMapPath::~RoadMapPath() { + delete [] _wayPoints; + } + + ///////////////////////////////////////////////////////////////////// + + void RoadMapPath::setWayPoint( size_t i, const Vector2 & pos ) { + assert( i < _wayPointCount && "Tried to set the position of an invalid waypoint" ); + _wayPoints[i].set( pos ); + } + + ///////////////////////////////////////////////////////////////////// + + void RoadMapPath::setPrefDirection( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ) { + // Assume that when I'm overlapping one node, that I can see the next + // Test to see if I can advance target way point + // while I'm overlapping current target, advance it + // assert that it is visible + // + // test to see if current target is visible + // if visible + // direction towards it + // current position last valid + // else + // direction towards last valid position + // TODO: This has flaws because the ObstacleKDTree is finding segments visible when it should not. + bool isVisible = false; + // TODO: Should I compute this blindly? Although it is used in potentially three places + // mostly, it won't be used. + Vector2 target = _goal->getTargetPoint( agent->_pos, agent->_radius ); + if ( _targetID < _wayPointCount ) { + isVisible = Menge::SPATIAL_QUERY->queryVisibility( agent->_pos, _wayPoints[ _targetID ], agent->_radius ); + } else { + isVisible = Menge::SPATIAL_QUERY->queryVisibility( agent->_pos, target, agent->_radius ); + } + size_t testID = _targetID + 1; + while ( testID < _wayPointCount && Menge::SPATIAL_QUERY->queryVisibility( agent->_pos, _wayPoints[ testID ], agent->_radius ) ) { + _targetID = testID; + isVisible = true; + ++testID; + } + if ( _targetID == _wayPointCount - 1 ) { + if ( Menge::SPATIAL_QUERY->queryVisibility( agent->_pos, target, agent->_radius ) ) { + ++_targetID; + isVisible = true; + } + } + // Visibility test + Vector2 dir; + if ( isVisible ) { + Vector2 curr( _targetID < _wayPointCount ? _wayPoints[ _targetID ] : target ); + dir = norm( curr - agent->_pos ); + _validPos = agent->_pos; + pVel.setTarget( curr ); + } else { + // This should never be the zero vector. + // _validPos is set when the current waypoint is visible + // this code is only achieved when it is NOT visible + // POSSIBLY, something weird could happen where the next waypoint isn't visible, but + // that breaks the earlier assertion. + dir = norm( _validPos - agent->_pos ); + pVel.setTarget( _validPos ); + } + pVel.setSingle( dir ); + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 RoadMapPath::getWayPoint( size_t i ) const { + assert( i <= _wayPointCount && "Requesting a waypoint with an invalid index" ); + return _wayPoints[ i ]; + } + +} // namespace Menge diff --git a/src/Menge/MengeCore/resources/RoadMapPath.h b/src/Menge/MengeCore/resources/RoadMapPath.h new file mode 100644 index 00000000..2392bbf2 --- /dev/null +++ b/src/Menge/MengeCore/resources/RoadMapPath.h @@ -0,0 +1,181 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file RoadMapPath.h + * @brief A path along a roadmap. + */ + +#ifndef __ROADMAP_PATH_H__ +#define __ROADMAP_PATH_H__ + +#include "mengeCommon.h" + +namespace Menge { + + class RoadMapPath; + + #ifdef _WIN32 + #include + /*! + * @brief A map from agent id to its path. + */ + typedef stdext::hash_map< size_t, RoadMapPath * > PathMap; + #else + #ifndef DOXYGEN_SHOULD_SKIP_THIS + #include + /*! + * @brief A map from agent id to its path. + */ + typedef std::tr1::unordered_map< size_t, RoadMapPath * > PathMap; + #endif // DOXYGEN_SHOULD_SKIP_THIS + #endif + + + namespace Agents { + class BaseAgent; + class PrefVelocity; + } + + namespace BFSM { + class Goal; + } + + /*! + * @brief A path on a roadmap between vertices + */ + class RoadMapPath { + public: + /*! + * @brief Constructor + * + * @param pointCount The number of waypoints in the path. + */ + RoadMapPath( size_t pointCount ); + + /*! + * @brief Destructor. + */ + ~RoadMapPath(); + + /*! + * @brief Sets the position of the ith waypoint. + * + * @param i The index of the waypoint. + * @param pos The location of the ith waypoint. + */ + void setWayPoint( size_t i, const Vector2 & pos ); + + /*! + * @brief Sets the ultimate goal. + * + * @param goal The ultimate goal + */ + inline void setGoalPos( const BFSM::Goal * goal ) { _goal = goal; } + + /*! + * @brief Sets the direction of the preferred velocity (and target). + * + * @param agent The agent to compute the preferred direciton for. + * @param pVel The preferred velocity to set. + */ + void setPrefDirection( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ); + + /*! + * @brief Reports the number of waypoints in the path. + * + * @returns The number of way points. This does *not* include the final + * goal point. So, at its simplest, this could be zero. + */ + inline size_t getWayPointCount() const { return _wayPointCount; } + + /*! + * @brief Returns the position of the ith waypoint. + * + * The index i is only validated in debug mode with an assertion. + * The ultimate goal is not included in the count. + * + * @param i The index of the desired waypoint. + * @returns The position of the ith waypoint. + */ + Vector2 getWayPoint( size_t i ) const; + + /*! + * @brief Returns the ultimate goal. + * + * @returns A pointer to the ultimate goal. + */ + const BFSM::Goal * getGoal() const { return _goal; } + + /*! + * @brief Returns the current target waypoint index + * + * @returns The index of the target waypoint. + */ + inline size_t getTargetID() const { return _targetID; } + + protected: + /*! + * @brief The ultimate goal. + */ + const BFSM::Goal * _goal; + + /*! + * @brief The last valid position -- validity means the target + * goal was visible. + */ + Vector2 _validPos; + + /*! + * @brief The index of the current target. + */ + size_t _targetID; + + /*! + * @brief The number of way points in the path. + */ + size_t _wayPointCount; + + /*! + * @brief The way points along the path. + */ + Vector2 * _wayPoints; + + }; +} // namespace Menge +#endif // __ROADMAP_PATH_H__ diff --git a/src/Menge/MengeCore/resources/Route.cpp b/src/Menge/MengeCore/resources/Route.cpp new file mode 100644 index 00000000..505fcdd9 --- /dev/null +++ b/src/Menge/MengeCore/resources/Route.cpp @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Route.h" +#include "NavMeshEdge.h" +#include "WayPortal.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PortalRoute + ///////////////////////////////////////////////////////////////////// + + PortalRoute::PortalRoute( unsigned int start, unsigned int end ): _startNode(start), _endNode(end), _maxWidth(1e6f), _bestSmallest(1e6f), _length(0.f) { + } + + ///////////////////////////////////////////////////////////////////// + + PortalRoute::~PortalRoute() { + } + + ///////////////////////////////////////////////////////////////////// + + void PortalRoute::appendWayPortal( const NavMeshEdge * edge, unsigned int node ) { + _length += edge->getNodeDistance(); + float w = edge->getWidth(); + _maxWidth = w < _maxWidth ? w : _maxWidth; + _portals.push_back( WayPortal( edge, node, edge->pointOnLeft( node ) ) ); + } + + ///////////////////////////////////////////////////////////////////// + + bool PortalRoute::isEquivalent( const PortalRoute * route ) { + const size_t PORTAL_COUNT = _portals.size(); + if ( PORTAL_COUNT == route->_portals.size () ) { + for ( size_t i = 0; i < PORTAL_COUNT; ++i ) { + if ( _portals[ i ]._nodeID != route->_portals[ i ]._nodeID ) { + break; + } + } + return true; + } + return false; + } +} // namespace Menge diff --git a/src/Menge/MengeCore/resources/Route.h b/src/Menge/MengeCore/resources/Route.h new file mode 100644 index 00000000..32155af7 --- /dev/null +++ b/src/Menge/MengeCore/resources/Route.h @@ -0,0 +1,184 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Route.h + * @brief The definition of a basic route through a navigation mesh + */ + +#ifndef __ROUTE_H__ +#define __ROUTE_H__ + +#include "WayPortal.h" +#include + +namespace Menge { + + // FORWARD DECLARATIONS + class PathPlanner; + class NavMeshEdge; + + /*! + * @brief The definition of a route through a navigation mesh from a + * start to an end node. + */ + class PortalRoute { + public: + /*! + * @brief Constructor + * + * @param start The index of the start node of the route. + * @param end The index of the end node of the rotue. + */ + PortalRoute( unsigned int start, unsigned int end ); + + /*! + * @brief Destructor. + */ + ~PortalRoute(); + + /*! + * @brief Returns the identifier for the first node on the route. + * + * @returns The first node's index. + */ + inline unsigned int getStartNode() const { return _startNode; } + + /*! + * @brief Returns the identifier for the destination node on the route. + * + * @returns The destination node's index. + */ + inline unsigned int getEndNode() const { return _endNode; } + + /*! + * @brief Reports the number of portals on the route. + * + * @returns The number of portals on the route. + */ + inline size_t getPortalCount() const { return _portals.size(); } + + /*! + * @brief Reports the node for the ith portal. + * + * @param i The index of the portal. + * @returns The index of the node the agent should be in when moving + * toward the ith portal. + */ + inline unsigned int getPortalNode( size_t i ) const { return _portals[ i ]._nodeID; } + + /*! + * @brief Gets the ith portal. + * + * @param i The path-local index of the portal. + * @returns A pointer to the ith portal. + */ + WayPortal * getPortal( size_t i ) { return &_portals[i]; } + + /*! + * @brief Gets a const version of the ith portal. + * + * @param i The path-local index of the portal. + * @returns A pointer to the ith portal. + */ + const WayPortal * getPortal( size_t i ) const { return &_portals[i]; } + + /*! + * @brief Appends a way portal to the path. + * + * @param edge The edge forming the portal + * @param node The node in which the agent should be traveling + * toward the edge + */ + void appendWayPortal( const NavMeshEdge * edge, unsigned int node ); + + /*! + * @brief Reports if the two routes have the same envelope. + * + * Two routes are equivalent if they have the same sequence of nav mesh nodes. + * It is assumed that they have the same start and end nodes. + * + * @param route The route to compare with this. + * @returns True if the two routes are equivalent. False otherwise. + */ + bool isEquivalent( const PortalRoute * route ); + + /*! + * @brief Report the length of the path. + */ + float getLength() const { return _length; } + + friend class PathPlanner; + + protected: + + /*! + * @brief The start node. + */ + unsigned int _startNode; + + /*! + * @brief The end node. + */ + unsigned int _endNode; + + /*! + * @brief The maximum width an agent can be to take this route + */ + float _maxWidth; + + /*! + * @brief The smallest agent width for which this has proven to + * be the optimal path. + */ + float _bestSmallest; + + /*! + * @brief The length of the route + */ + float _length; + + /*! + * @brief The list of portals to pass through along the route + */ + std::vector< WayPortal > _portals; + }; +} // namespace Menge + +#endif // __ROUTE_H__ + diff --git a/src/Menge/MengeCore/resources/VectorField.cpp b/src/Menge/MengeCore/resources/VectorField.cpp new file mode 100644 index 00000000..38a6971c --- /dev/null +++ b/src/Menge/MengeCore/resources/VectorField.cpp @@ -0,0 +1,267 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VectorField.h" +#include "ResourceManager.h" +#include +#include +#include + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of VectorField + ///////////////////////////////////////////////////////////////////// + + const std::string VectorField::LABEL("vecfield"); + + ///////////////////////////////////////////////////////////////////// + + VectorField::VectorField( const std::string & fileName ):Resource(fileName) { + _resolution[0] = _resolution[1] = 0; + _cellSize = 0.f; + _data = 0x0; + } + + ///////////////////////////////////////////////////////////////////// + + VectorField::~VectorField() { + freeDataArray(); + } + + ///////////////////////////////////////////////////////////////////// + + void VectorField::setDimensions( float width, float height ) { + float ratio = width / _cellSize; + int colCount = (int)ratio; + if ( ratio - colCount > 0.f ) ++colCount; + ratio = height / _cellSize; + int rowCount = (int)ratio; + if ( ratio - rowCount > 0.f ) ++rowCount; + _resolution[0] = rowCount; + _resolution[1] = colCount; + } + + ///////////////////////////////////////////////////////////////////// + + void VectorField::initDataArray() { + freeDataArray(); + const int ROW_COUNT = _resolution[0]; + const int COL_COUNT = _resolution[1]; + _data = new Vector2*[ ROW_COUNT ]; + for ( int r = 0; r < ROW_COUNT; ++r ) { + _data[r] = new Vector2[ COL_COUNT ]; + } + } + + ///////////////////////////////////////////////////////////////////// + + void VectorField::freeDataArray() { + if ( _data ) { + for ( int r = 0; r < _resolution[0]; ++r ) { + delete [] _data[r]; + } + delete _data; + _data = 0x0; + } + } + + ///////////////////////////////////////////////////////////////////// + + void VectorField::getCell( const Vector2 & pos, int & r, int & c ) { + assert( _data != 0x0 && "Requesting a field value without having field data" ); + Vector2 offset = pos - _minPoint; + offset /= _cellSize; + c = (int)offset.x(); + if ( c < 0 ) c = 0; + else if ( c >= _resolution[1] ) c = _resolution[1] - 1; + + r = (int)offset.y(); + if ( r < 0 ) r = 0; + else if ( r >= _resolution[0] ) r = _resolution[0] - 1; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 VectorField::getFieldValue( int row, int col ) const { + assert( row >= 0 && row < _resolution[0] && "Invalid row index" ); + assert( col >= 0 && col < _resolution[1] && "Invalid column index" ); + return _data[ row ][ col ]; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 VectorField::getFieldValue( const Vector2 & pos ) { + assert( _data != 0x0 && "Requesting a field value without having field data" ); + int row, col; + getCell( pos, row, col ); + + return _data[ row ][ col ]; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 VectorField::getFieldValueInterp( const Vector2 & pos ) { + // NOTE: this doesn't use anything smart when it comes to performing + // the bilinear interpolation. The x and y components of the vector + // are interpolated independently + assert( _data != 0x0 && "Requesting a field value without having field data" ); + int rowIndex, colIndex; + getCell( pos, rowIndex, colIndex ); + + // Compute center of target cell + Vector2 center = Vector2( colIndex + 0.5f, rowIndex + 0.5f ) * _cellSize + _minPoint; + Vector2 weight = ( pos - center ) / _cellSize; + const float WX = weight.x(); + const float WY = weight.y(); + + Vector2 value = _data[ rowIndex ][ colIndex ]; + + // if I'm in the center its simple + const int ROW_COUNT = _resolution[0]; + const int COL_COUNT = _resolution[1]; + if ( WX >= 0.f && colIndex < COL_COUNT - 1 ) { + // interpolate with cells to the right + value = _data[rowIndex][colIndex] * ( 1 - WX ) + _data[ rowIndex ][colIndex + 1] * WX; + if ( WY >= 0.f && rowIndex < ROW_COUNT - 1 ) { + Vector2 val2 = _data[rowIndex+1][colIndex] * ( 1 - WX ) + _data[ rowIndex+1][colIndex + 1] * WX; + value *= (1 - WY ); + value += val2 * WY; + } else if ( WY < 0 && rowIndex > 0 ) { + Vector2 val2 = _data[rowIndex-1][colIndex] * ( 1 - WX ) + _data[ rowIndex-1][colIndex + 1] * WX; + value *= (1 + WY ); + value -= val2 * WY; + } + } else if ( WX < 0.f && colIndex > 0 ) { + // interpolate with cells to the right + value = _data[rowIndex][colIndex] * ( 1 + WX ) - _data[ rowIndex ][colIndex - 1] * WX; + if ( WY >= 0.f && rowIndex < ROW_COUNT - 1 ) { + Vector2 val2 = _data[rowIndex+1][colIndex] * ( 1 + WX ) - _data[ rowIndex+1][colIndex - 1] * WX; + value *= (1 - WY ); + value += val2 * WY; + } else if ( WY < 0 && rowIndex > 0 ) { + Vector2 val2 = _data[rowIndex-1][colIndex] * ( 1 + WX ) - _data[ rowIndex-1][colIndex - 1] * WX; + value *= (1 + WY ); + value -= val2 * WY; + } + } else { + if ( WY >= 0.f && rowIndex < ROW_COUNT - 1 ) { + value = _data[rowIndex][colIndex] * ( 1 - WY ) + _data[ rowIndex+1 ][colIndex] * WY; + } else if ( WY < 0 && rowIndex > 0 ) { + value = _data[rowIndex][colIndex] * ( 1 + WY ) - _data[ rowIndex-1 ][colIndex] * WY; + } + } + + return value; + } + + ///////////////////////////////////////////////////////////////////// + + Resource * VectorField::load( const std::string & fileName ) { + std::ifstream f; + f.open( fileName.c_str(), std::ios::in ); + if ( ! f.is_open() ) { + logger << Logger::ERR_MSG << "Error opening the VectorField file definition: " << fileName << "\n"; + return 0x0; + } + + VectorField * field = new VectorField( fileName ); + f >> field->_resolution[0] >>field-> _resolution[1]; + f >> field->_cellSize; + float x, y; + f >> x >> y; + field->_minPoint = Vector2( x, y ); + field->initDataArray(); + for ( int r = 0; r < field->_resolution[0]; ++r ) { + for ( int c = 0; c < field->_resolution[1]; ++c ) { + if ( f >> x >> y ) { + field->_data[r][c] = Vector2( x, y ); + } else { + logger << Logger::ERR_MSG << "Format error in the VectorField file definition: " << fileName << "\n"; + logger << "\tTried to read a vector at position: (" << r << ", " << c << "), but no data existed\n"; + field->destroy(); + f.close(); + return 0x0; + } + } + } + f.close(); + + return field; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 VectorField::getMaximumPoint() const { + return getSize() + _minPoint; + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 VectorField::getSize() const { + float width = _resolution[1] * _cellSize; + float height = _resolution[0] * _cellSize; + return Vector2( width, height ); + } + + ///////////////////////////////////////////////////////////////////// + + Logger & operator<< ( Logger & out, const VectorField & vf ) { + out << "Vector Field:\n"; + out << "\tMinimum point: " << vf._minPoint << "\n"; + out << "\tCell size: " << vf._cellSize << "\n"; + out << "\t(width,height): " << vf.getSize() << "\n"; + return out; + } + + ///////////////////////////////////////////////////////////////////// + + VectorFieldPtr loadVectorField( const std::string & fileName ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &VectorField::load, VectorField::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No resource available\n"; + throw ResourceException(); + } + VectorField * vf = dynamic_cast< VectorField * >( rsrc ); + if ( vf == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a VectorField\n"; + throw ResourceException(); + } + return VectorFieldPtr( vf ); + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/VectorField.h b/src/Menge/MengeCore/resources/VectorField.h new file mode 100644 index 00000000..3cd2a8b1 --- /dev/null +++ b/src/Menge/MengeCore/resources/VectorField.h @@ -0,0 +1,267 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VectorField.h + * @brief The definition of a 2D vector field. + */ + +#ifndef __VECTOR_FIELD_H__ +#define __VECTOR_FIELD_H__ + +// A 2D vector field +// The field itself need not be square, but the cells are. +// STL +#include +#include +#include "Resource.h" +#include "mengeCommon.h" + +namespace Menge { + + /*! + * @brief A simple 2D vector field. + * + * The field is defined by the location of its bottom, left-hand corner, the size + * of the space the grid should cover and the size of each, square cell. + */ + class MENGE_API VectorField : public Resource { + public: + /*! + * @brief Default constructor. + * + * @param fileName The name of the file which contains the vector field definition. + */ + VectorField( const std::string & fileName ); + + protected: + /*! + * @brief Destructor. + */ + virtual ~VectorField(); + + public: + + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const { return LABEL; } + + /*! + * @brief Reports the cell the a point is in. + * + * TODO: Determine what happens if pos is off the grid + * + * @param pos The point to test. + * @param r A reference to the row index -- this is to be set by the + * function. + * @param c A reference to the column index -- this is to be set by the + * function. + */ + void getCell( const Vector2 & pos, int & r, int & c ); + + /*! + * @brief Returns the value of the field for the given CELL address + * + * The row and column values are only validated in debug mode, using an assertion. + * + * @param row The index of the row + * @param col The index of the column. + * @returns The vector value of the cell at (row, col) + */ + Vector2 getFieldValue( int row, int col ) const; + + /*! + * @brief Returns the value of the field for the given position. + * + * This uses a "nearest" value look-up. The cell center which is closest to the + * query point is used. That means, points that lie outside the field will get + * the vector value of the closest cell in the grid. + * + * @param pos The position to read the field's vector value. + * @returns The vector value of the cell center closest to pos. + */ + Vector2 getFieldValue( const Vector2 & pos ); + + /*! + * @brief Returns the value of the field for the given position. + * + * This uses a bi-linear interpolation value. The four surrounding cells' values + * are combined linearly based on relative distances. If the point lies outside + * the field, then only two, or possibly only one cell is used. + * + * @param pos The position to read the field's vector value. + * @returns The vector value of the cell center closest to pos. + */ + Vector2 getFieldValueInterp( const Vector2 & pos ); + + /*! + * @brief Parses a vector field definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a VectorField, but to a Resource. The ResourceManager + * uses it to load and instantiate VectorField instances. + * + * @param fileName The path to the file containing the VectorField + * definition. + * @returns A pointer to the new VectorField (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief Reports the minimum extent of the field. + * + * @returns The minimum extent of the field. + */ + Vector2 getMinimumPoint() const { return _minPoint; } + + /*! + * @brief Reports the maximum extent of the field. + * + * @returns The maximum extent of the field. + */ + Vector2 getMaximumPoint() const; + + /*! + * @brief Reports the size of the field (along both axes). + * + * @returns The size of the field. + */ + Vector2 getSize() const; + + /*! + * @brief Reports the number of rows in the field. + * + * @returns The number of rows. + */ + inline int getRowCount() const { return _resolution[0]; } + + /*! + * @brief Reports the number of columns in the field. + * + * @returns The number of columns. + */ + inline int getColCount() const { return _resolution[1]; } + + /*! + * @brief Reports the number of rows in the field. + * + * @returns The number of rows. + */ + inline float getCellSize() const { return _cellSize; } + + /*! + * @brief Overloaded streaming output operator to print the field to an + * output stream. + * + * @param out The output stream. + * @param vf The vector field to convert to a string. + * @returns The output stream. + */ + friend Logger & operator<< ( Logger & out, const VectorField & vf ); + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + protected: + /*! + * @brief The minimum extent of the vector field. + */ + Vector2 _minPoint; + + /*! + * @brief The resolution (in cells) of the field's grid (rowCount, colCount) + */ + int _resolution[2]; + + /*! + * @brief Size of the grid cell. + */ + float _cellSize; + + /*! + * @brief The 2D array of vector data for each cell. + */ + Vector2 ** _data; + + /*! + * @brief Computes the appropriate resolution of the grid. + * + * It uses the pre-determined cell size to determine the resolution that + * tightly spans the size given (although, if the size is not an integer + * multiple of the cell size, the resultant field will be *slightly* larger + * (i.e. the extra extent will be less than the cell size). + * + * @param width The desired size of the field along the x-axis. + * @param height The desired size of the field along the y-axis. + */ + void setDimensions( float width, float height ); + + /*! + * @brief Given the stored resolution, intializes the data array. + */ + void initDataArray(); + + /*! + * @brief frees the data array. + */ + void freeDataArray(); + }; + + /*! + * @brief The definition of the managed pointer for VectorField data + */ + typedef ResourcePtr< VectorField > VectorFieldPtr; + + /*! + * @brief Loads the vector field of the given name + * + * @param fileName The name of the file containing the vector field definition. + * @returns The VectorFieldPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ + VectorFieldPtr loadVectorField( const std::string & fileName ) throw ( ResourceException ); +} // namespace Menge + +#endif // __VECTOR_FIELD_H__ diff --git a/src/Menge/MengeCore/resources/WayPortal.cpp b/src/Menge/MengeCore/resources/WayPortal.cpp new file mode 100644 index 00000000..6352c615 --- /dev/null +++ b/src/Menge/MengeCore/resources/WayPortal.cpp @@ -0,0 +1,76 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "WayPortal.h" + +namespace Menge { + + ///////////////////////////////////////////////////////////////////// + // Implementation of WayPortal + ///////////////////////////////////////////////////////////////////// + + WayPortal::WayPortal( const NavMeshEdge * edge, unsigned int nodeID, bool p0IsLeft ): _edge(edge), _nodeID(nodeID), _p0IsLeft(p0IsLeft) { + } + + ///////////////////////////////////////////////////////////////////// + + void WayPortal::setPreferredDirection( const Vector2 & pos, float radius, const Vector2 & dir, Agents::PrefVelocity & pVel ) const { + _edge->setClearDirections( pos, radius, dir, pVel ); + + } + + ///////////////////////////////////////////////////////////////////// + + Vector2 WayPortal::intersectionPoint( const Vector2 & point, const Vector2 & dir ) const { + Vector2 pDir = _edge->getDirection(); + Vector2 p0 = _edge->getP0(); + float denom = det( pDir, dir ); + //if ( fabs( denom ) <= EPS ) { + // // If the line is parallel with the portal, just use the point + // // This is a horrible, horrible hack. + // return point; + //} + assert( fabs( denom ) > EPS && "Parallel lines don't intersect" ); + + float num = det( dir, p0 - point ); + float s = num / denom; + return p0 + s * pDir; + } + + ///////////////////////////////////////////////////////////////////// +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/resources/WayPortal.h b/src/Menge/MengeCore/resources/WayPortal.h new file mode 100644 index 00000000..bdcca4bd --- /dev/null +++ b/src/Menge/MengeCore/resources/WayPortal.h @@ -0,0 +1,160 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file WayPortal.h + * @brief Defines a way portal for a navigation mesh route/path. + */ + +#ifndef __WAY_PORTAL_H__ +#define __WAY_PORTAL_H__ + +#include "NavMeshEdge.h" + +namespace Menge { + + // FORWARD DECLARATIONS + class PortalRoute; + class PortalPath; + namespace Agents { + class PrefVelocity; + } + + /*! + * @brief The basic structure defining a way "point" along a path + * through a navigation mesh. It consists of the navigation mesh + * edge to pass through and the node one should be in while heading + * to the edge. + */ + class WayPortal { + public: + /*! + * @brief Constructor + * + * @param edge The NavigationMeshEdge which serves as the + * immediate goal for this WayPortal. + * @param nodeID The nav mesh node that an agent should be in + * while heading for this node. + * @param p0IsLeft Indicates if the p0 value of the edge is on the + * left, when faced from inside the node. + */ + WayPortal( const NavMeshEdge * edge, unsigned int nodeID, bool p0IsLeft ); + + /*! + * @brief Retrives the left physical vertex of the portal. + * + * @returns The position of the left physical vertex, as viewed + * from inside _nodeID. + */ + inline Vector2 getLeft() const { return _p0IsLeft ? _edge->getP0() : _edge->getP1(); } + + /*! + * @brief Retrives the position in the portal offset from the left physical vertex. + * + * @param offset The distance offset from the left physical vertex. + * @returns The position offset from the left physical vertex, as viewed + * from inside _nodeID. + */ + inline Vector2 getLeft( float offset ) const { return _p0IsLeft ? _edge->getP0( offset ) : _edge->getP1( offset ); } + + /*! + * @brief Retrives the right physical vertex of the portal. + * + * @returns The position of the right physical vertex, as viewed + * from inside _nodeID. + */ + inline Vector2 getRight() const { return _p0IsLeft ? _edge->getP1() : _edge->getP0(); } + + /*! + * @brief Retrives the position in the portal offset from the right physical vertex. + * + * @param offset The distance offset from the right physical vertex. + * @returns The position offset from the right physical vertex, as viewed + * from inside _nodeID. + */ + inline Vector2 getRight( float offset ) const { return _p0IsLeft ? _edge->getP1( offset ) : _edge->getP0( offset ); } + + /*! + * @brief Computes the intersection point of the given line with this portal. + * + * This algorithm ASSUMES that the line DOES intersect the portal. The behavior is undefined + * if they don't intersect. + * + * @param point A point on the line to test. + * @param dir A direction vector defining the position of the line. + * @returns A point, on the portal, at which the line intersects. + */ + Vector2 intersectionPoint( const Vector2 & point, const Vector2 & dir ) const; + + /*! + * @brief Sets the directions on the preferred velocity based on the wayportal. + * + * @param pos The position of the agent. + * @param radius The radius of the agent. + * @param dir Preferred direction of the agent. Direction is NOT assumed to + * be of unit-length. + * @param pVel The preferred velocity + */ + void setPreferredDirection( const Vector2 & pos, float radius, const Vector2 & dir, Agents::PrefVelocity & pVel ) const; + + friend class PortalRoute; + friend class PortalPath; + + protected: + /*! + * @brief The edge which serves as goal. + */ + const NavMeshEdge * _edge; + + /*! + * @brief The index of the node in which the agent is traveling toward + * the edge. It should be true that the specified node is + * attached/connected to the given edge. + */ + unsigned int _nodeID; + + /*! + * @brief Reports if the edge's P0 is the left vertex. + * Left is defined based on moving across the portal from + * the node indicated by _nodeID; + */ + bool _p0IsLeft; + }; + +} // namespace Menge +#endif // __WAY_PORTAL_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/GLViewer.cpp b/src/Menge/MengeCore/viewer/GLViewer.cpp new file mode 100644 index 00000000..bc03dea6 --- /dev/null +++ b/src/Menge/MengeCore/viewer/GLViewer.cpp @@ -0,0 +1,700 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + + +#ifdef _MSC_VER +#include "windows.h" +#endif + +// Viewer +#include "GLViewer.h" +#include "ViewConfig.h" +#include "ScreenGrab.h" +#include "Profiler.h" +#include "Watermark.h" + +// menge runtime +#include "os.h" + +// Scene graph +#include "Select.h" +#include "Context.h" +#include "TextWriter.h" +#include "XformMatrix.h" +#include "GLContextManager.h" +#include "image.h" +#include "shapes.h" + +// standard library +#include +#include +#include + +namespace Menge { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + std::string useMessage("\nViewer controls:\n" \ + " Quit the program ............ Ctrl + q\n"\ + " Camera controls:\n" \ + " Ctrl + Left Mouse ......... ROTATION\n" \ + " Ctrl + Shift + Left Mouse.. MOVE\n" \ + " Shift + Left Mouse ........ ZOOM\n" \ + " 'o' ....................... Orthographic view\n" \ + " 'p' ....................... Perspective view\n" \ + " 'x' ....................... Look along x-axis\n" \ + " Shift + 'x'................ Look along negative x-axis\n"\ + " 'y' ....................... Look along y-axis\n" \ + " Shift + 'y'................ Look along negative y-axis\n"\ + " 'z' ....................... Look along z-axis\n" \ + " Shift + 'z'................ Look along negative z-axis\n"\ + " Ctrl + 'c'................. Display camera parameters to the console\n"\ + " Ctrl + '1'-'9'............. Switch cameras (if a camera exists)\n"\ + " Playback:\n" \ + " spacebar .................. Stop/start playback\n" \ + " RIGHT arrow ............... Advance one frame (when stopped)\n" \ + " Output images ............... Ctrl + o\n"\ + ); + + size_t FULL_FRAME = 0; + size_t SCENE_UPDATE = 0; + size_t FULL_DRAW = 0; + size_t BUFFER_SWAP = 0; + +#endif // DOXYGEN_SHOULD_SKIP_THIS + + namespace Vis { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR GLViewer + /////////////////////////////////////////////////////////////////////////// + + Uint32 GLViewer::FLAGS = SDL_OPENGL | SDL_DOUBLEBUF | SDL_RESIZABLE; + + /////////////////////////////////////////////////////////////////////////// + + GLViewer::GLViewer( int width, int height ): _width( width ), _height( height ), _scene( 0 ), _downX( 0 ), + _downY(0), _update(false), _drawWorldAxis(false), + _showFPS(false), _fpsDisplayTimer(10), _pause(true), _running(true), + _viewTime(0.f), + _bgColor(0.74f, 0.69f, 0.64f), _stepSize(1 / 120.f), _bgImg(0x0), + _dumpImages(false), _validDumpPath(true), _dumpPath( ".\\" ), _imgCount(0) + { + ImageData::start(); + FULL_FRAME = addTimer( "Full frame " ); + SCENE_UPDATE = addTimer( " scene update " ); + FULL_DRAW = addTimer( " scene draw " ); + BUFFER_SWAP = addTimer( " buffer swap " ); + } + + /////////////////////////////////////////////////////////////////////////// + + GLViewer::GLViewer( ViewConfig & cfg ): _width(cfg._width), _height(cfg._height), _scene(0x0), _downX(0), + _downY(0), _update(false), _drawWorldAxis(false), + _showFPS(false), _fpsDisplayTimer(10), _pause(true), _running(true), + _viewTime(0.f), + _bgColor(0.74f, 0.69f, 0.64f), _stepSize(1 / 120.f), _bgImg(0x0), + _dumpImages(false), _validDumpPath(true), _dumpPath( ".\\" ), _imgCount(0) + { + ImageData::start(); + FULL_FRAME = addTimer( "Full frame " ); + SCENE_UPDATE = addTimer( " scene update " ); + FULL_DRAW = addTimer( " scene draw " ); + BUFFER_SWAP = addTimer( " buffer swap " ); + + // initialize from config + cfg.setCameras( _cameras ); + cfg.setLights( _lights ); + // TODO: Set this in the view config file + SceneGraph::TextWriter::Instance()->setDefaultColor( cfg._fontColor[0], cfg._fontColor[1], cfg._fontColor[2], cfg._fontColor[3] ); + SceneGraph::TextWriter::Instance()->setFont( cfg._fontName ); + _currCam = 0; + + if ( cfg._bgImg != "" ) { + if ( ! setBGImage( cfg._bgImg ) ) { + logger << Logger::ERR_MSG << "Unable to load background image: " << cfg._bgImg << "\n"; + } + } + _waterMark = cfg._waterMark; + cfg._waterMark = 0x0; + } + + /////////////////////////////////////////////////////////////////////////// + + GLViewer::~GLViewer() { + if ( _scene != 0x0 ) { + //delete _scene; TODO: Figure out why navigation mesh causes problems here + _scene = 0x0; + } + + if ( _bgImg != 0x0 ) { + delete _bgImg; + } + SDL_Quit(); + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLViewer::initViewer( const std::string & title ) { + if ( ! initSDL( title ) ) return false; + initGL(); + SceneGraph::initShapes(); + resizeGL( _width, _height ); + + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::run() { + bool redraw = true; + float time = 0.f; + _fpsDisplayTimer.start(); + + while ( _running ) { + SDL_Event e; + while ( SDL_PollEvent( &e ) ) { + if( e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) { + redraw = handleKeyboard( e ) || redraw; + } else if( e.type == SDL_QUIT ) { + _running = false; + redraw = false; + break; + } else if( e.type == SDL_VIDEOEXPOSE ) { + redraw = true; + } else if( e.type == SDL_MOUSEMOTION || + e.type == SDL_MOUSEBUTTONDOWN || + e.type == SDL_MOUSEBUTTONUP ) { + redraw = handleMouse( e ) || redraw; + } else if ( e.type == SDL_VIDEORESIZE ) { + resizeGL( e.resize.w, e.resize.h ); + redraw = true; + } + } + if ( !_pause ) startTimer( FULL_FRAME ); + if ( redraw || _update || !_pause ) { + + // draw stuff + if ( _scene && ( !_pause || _update ) ) { + startTimer( SCENE_UPDATE ); + try { + redraw = _scene->updateScene( _viewTime ); + } catch ( SceneGraph::SystemStopException ) { + // When a system sends an exception that things are over + // pause everything + std::cout << "System stopped!\n"; + _pause = true; + } + if (!_update ) { + offsetTime( _stepSize ); + } + stopTimer( SCENE_UPDATE ); + } + if ( redraw ) { + startTimer( FULL_DRAW ); + drawGL(); + stopTimer( FULL_DRAW ); + + startTimer( BUFFER_SWAP ); + SDL_GL_SwapBuffers(); + stopTimer( BUFFER_SWAP ); + redraw = false; + } + if ( !_pause ) lapTimer( FULL_FRAME ); + } + + if ( ( !_pause || _update ) && _dumpImages ) { + std::stringstream fullPath; + fullPath << _dumpPath << "img"; + fullPath << std::setfill( '0' ) << std::setw( 6 ) << ++_imgCount << ".png"; + snapshotPNG( _width, _height, fullPath.str().c_str() ); + } + _update = false; + } + printAverages(); + + _scene->finish(); + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLViewer::setBGImage( const std::string & imgName ) { + _bgImg = loadImage( imgName ); + return _bgImg != 0x0; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::clearBGImage() { + if ( _bgImg != 0x0 ) { + delete _bgImg; + _bgImg = 0x0; + } + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLViewer::initSDL( const std::string & title ) { + if( SDL_Init( SDL_INIT_VIDEO ) != 0 ) { + logger << Logger::ERR_MSG << "Unable to initialize SDL: " << SDL_GetError(); + SDL_Delay( 3000 ); + return false; + } + + SDL_WM_SetCaption( title.c_str(), 0x0 ); + #if _MSC_VER <= 1400 + SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ); + #endif + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); + SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); + + if ( !SDL_SetVideoMode( _width, _height, 32, FLAGS ) ) { + logger << Logger::ERR_MSG << "Unable to set video mode: " << SDL_GetError(); + SDL_Delay( 3000 ); + SDL_Quit(); + return false; + } + SDL_EnableKeyRepeat( 100, 33 ); // start repeat after tenth of a second and signal at 30 Hz + + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::resizeGL( int w, int h ) { + _width = w; + _height = h; + if ( _height == 0 ) { + _height = 1; + } + SDL_SetVideoMode( _width, _height, 32, FLAGS ); + + // Inform all dependent entities that the context has changed + newGLContext(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::setScene( SceneGraph::GLScene * scene ) { + if ( _scene && scene != _scene ) { + delete _scene; + } + _scene = scene; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::newGLContext() { + SceneGraph::TextWriter::Instance()->resize( _width, _height ); + SceneGraph::TextWriter::Instance()->newGLContext(); + initGL(); + GLContextManager::newGLContext(); + if ( _scene ) { + _scene->newGLContext(); + } + // Re-initialize the cameras + for ( size_t i = 0; i < _cameras.size(); ++i ) { + _cameras[i].setViewport( _width, _height ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::initGL() { + glEnable( GL_NORMALIZE ); + glShadeModel( GL_SMOOTH ); + glClearColor( _bgColor.x(), _bgColor.y(), _bgColor.z(), 0.f ); + glClearDepth( 1.f ); + glEnable(GL_DEPTH_TEST); + if ( _lights.size() > 0 ) { + initLighting(); + } else { + glDisable( GL_LIGHTING ); + } + + glEnable( GL_COLOR_MATERIAL ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::drawGL() { + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + if ( _bgImg ) { + glPushAttrib( GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT ); + glDisable( GL_LIGHTING ); + glDepthMask( GL_FALSE ); + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, _width, 0.0, _height, -1.0f, 1.0f ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + _bgImg->bind(); + glColor3f( 1.f, 1.f, 1.f ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.f, 1.f ); + glVertex3f( 0.f, 0.f, 0.f ); + glTexCoord2f( 1.f, 1.f ); + glVertex3f( (float)_width, 0.f, 0.f ); + glTexCoord2f( 1.f, 0.f ); + glVertex3f( (float)_width, (float)_height, 0.f ); + glTexCoord2f( 0.f, 0.f ); + glVertex3f( 0.f, (float)_height, 0.f ); + glEnd(); + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopAttrib(); + } + if ( _scene ) { + _scene->drawGL( _cameras[ _currCam ], _lights, _width, _height ); + } + // various view decorations + // world axis + if ( _drawWorldAxis ) drawWorldAxis(); + + const int STRING_LEN = 100; + char msg[STRING_LEN]; + // UI messsages + float time = _fpsDisplayTimer.lap(); + if ( _showFPS ) { + #ifdef TIME_CROWD + sprintf_s( msg, STRING_LEN, "FPS: %.1f UPDATE TIME: %.1f microsec SIM TIME: %.2f s", 1.f / time, 1000.f * averageTime(SCENE_UPDATE), _viewTime ); + #else + sprintf_s( msg, STRING_LEN, "FPS: %.1f SIM TIME: %.2f s", 1.f / time, _viewTime ); + #endif + SceneGraph::TextWriter * writer = SceneGraph::TextWriter::Instance(); + writer->printAlignText( std::string(msg), SceneGraph::TextWriter::CENTER_BOTTOM, 15, 5.f, 5.f ); + } + if ( _waterMark ) { + _waterMark->drawGL( (float)_width, (float)_height ); + } + if ( _dumpImages ) { + drawRecordingFrame(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::drawRecordingFrame() const { + + GLfloat width = (GLfloat)_width; + GLfloat height = (GLfloat)_height; + // set up rendering + glPushAttrib( GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT ); + glDisable( GL_LIGHTING ); + glDisable( GL_DEPTH_TEST ); + glDepthMask( GL_FALSE ); + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, _width, 0.0, _height, -1.0f, 1.0f ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glColor4f( 1.f, 0.f, 0.f, 1.f ); + + glBegin( GL_LINE_STRIP ); + glVertex3f( 1.f, 1.f, 0.f ); + glVertex3f( width, 1.f, 0.f ); + glVertex3f( width, height, 0.f ); + glVertex3f( 1.f, height, 0.f ); + glVertex3f( 1.f, 1.f, 0.f ); + glEnd(); + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopAttrib(); + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLViewer::handleMouse( SDL_Event & e ) { + bool redraw = false; + SceneGraph::ContextResult result( false, false ); + if ( _scene ) { + result = _scene->handleMouse( e ); + redraw = result.needsRedraw(); + } + if ( ! result.isHandled() ) { + SDLMod mods = SDL_GetModState(); + int x = e.button.x; + int y = e.button.y; + + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + + bool rotate = hasCtrl && !(hasAlt || hasShift ); + bool pan = !hasAlt && hasCtrl && hasShift; + bool zoom = hasShift && !(hasAlt || hasCtrl ); + + if ( e.type == SDL_MOUSEMOTION ) { + if ( e.button.button == SDL_BUTTON_LEFT ) { + if ( rotate ) { // orbit around the camera + float deltaX = ( x - _downX ) * 0.0075f; // TODO: get rid of this magic number + float deltaY = ( y - _downY ) * 0.0075f; // TODO: get rid of this magic number + _cameras[ _currCam ].orbitHorizontalAxis( deltaY ); + _cameras[ _currCam ].orbitVerticalAxis( -deltaX ); + } else if ( pan ) { + /// This scale should be the size of a pixel at the target depth + float deltaX = ( x - _downX ) * 0.0025f; + _cameras[ _currCam ].truck( -deltaX ); + float deltaY = ( y - _downY ) * 0.0025f; + _cameras[ _currCam ].crane( deltaY ); + } else if ( zoom ) { + const float scale = 1.f / 5.0f; + float deltaY = ( y - _downY ) * scale; + _cameras[ _currCam ].zoom( -deltaY ); + } + _downX = x; + _downY = y; + redraw = true; + } + } else if ( e.type == SDL_MOUSEBUTTONDOWN ) { + if ( e.button.button == SDL_BUTTON_LEFT ) { + _downX = e.button.x; + _downY = e.button.y; + if ( !( hasCtrl || hasAlt || hasShift ) && _scene != 0x0 ) { + // TODO: This won't work when there are widgets + // Would this be better off embedded into the scene? + // After all, a manipulator merely has a special context... + // So, should a context have some kind of drawable function? + // + int selectPoint[2] = { _downX, _downY }; + redraw = _scene->selectGL( _cameras[ _currCam ], _width, _height, &selectPoint[0] ); + } + } else if ( e.button.button == SDL_BUTTON_RIGHT ) { + } else if ( e.button.button == SDL_BUTTON_WHEELUP ) { + float amount = 0.5; + if ( hasCtrl ) amount *= 2; + if ( hasAlt ) amount *= 2; + if ( hasShift ) amount *= 2; + _cameras[ _currCam ].zoom( amount ); + redraw = true; + } else if ( e.button.button == SDL_BUTTON_WHEELDOWN ) { + float amount = -0.5; + if ( hasCtrl ) amount *= 2; + if ( hasAlt ) amount *= 2; + if ( hasShift ) amount *= 2; + _cameras[ _currCam ].zoom( amount ); + redraw = true; + } + } else if ( e.type == SDL_MOUSEBUTTONUP ) { + + } else { + logger << Logger::ERR_MSG << "handleMouse called with invalid event type: " << (int)e.type << "\n"; + } + } + + return redraw; + } + + /////////////////////////////////////////////////////////////////////////// + + bool GLViewer::handleKeyboard( SDL_Event & e ) { + bool redraw = false; + SceneGraph::ContextResult result( false, false ); + if ( _scene ) { + result = _scene->handleKeyboard( e ); + redraw = result.needsRedraw(); + } + + if ( ! result.isHandled() ) { + SDLMod mods = SDL_GetModState(); + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + if ( e.key.type == SDL_KEYDOWN ) { + if ( noMods ) { + if ( e.key.keysym.sym == SDLK_f ) { + _showFPS = !_showFPS; + redraw = true; + } else if ( e.key.keysym.sym == SDLK_h ) { + std::cout << useMessage; + } else if ( e.key.keysym.sym == SDLK_a ) { + _drawWorldAxis = !_drawWorldAxis; + redraw = true; + } else if ( e.key.keysym.sym == SDLK_SPACE ) { + _pause = !_pause; + redraw = true; + } else if ( e.key.keysym.sym == SDLK_RIGHT ) { + if ( _pause ) { + offsetTime( _stepSize ); + redraw = _update = true; + } + } else if ( e.key.keysym.sym == SDLK_x ) { + _cameras[ _currCam ].viewXAxis(); + redraw = true; + } else if ( e.key.keysym.sym == SDLK_y ) { + _cameras[ _currCam ].viewYAxis(); + redraw = true; + } else if ( e.key.keysym.sym == SDLK_z ) { + _cameras[ _currCam ].viewZAxis(); + redraw = true; + } else if ( e.key.keysym.sym >= SDLK_1 && e.key.keysym.sym <= SDLK_9 ) { + size_t camIndex = (size_t)e.key.keysym.sym - (size_t)SDLK_1; + assert( camIndex <= 8 && "Invalid camera index!\n" ); + if ( camIndex < _cameras.size() && _currCam != camIndex ) { + _currCam = camIndex; + _cameras[ _currCam ].setActive(); + redraw = true; + } + } else if ( e.key.keysym.sym == SDLK_o ) { + _cameras[ _currCam ].setOrtho(); + redraw = true; + } else if ( e.key.keysym.sym == SDLK_p ) { + _cameras[ _currCam ].setPersp(); + redraw = true; + } + } else if ( hasCtrl && !hasShift && !hasAlt) { + if ( e.key.keysym.sym == SDLK_q ) { + _running = false; + } else if ( e.key.keysym.sym == SDLK_c ) { + std::cout << "View:\n"; + std::cout << "\t( " << _width << ", " << _height << " )\n"; + _cameras[ _currCam ].outputState(); + } + else if ( e.key.keysym.sym == SDLK_o ) { + _dumpImages = !_dumpImages && _validDumpPath; + redraw = true; + } + } else if ( !hasCtrl && hasShift && !hasAlt ) { + if ( e.key.keysym.sym == SDLK_x ) { + _cameras[ _currCam ].viewXAxis( false ); + redraw = true; + } else if ( e.key.keysym.sym == SDLK_y ) { + _cameras[ _currCam ].viewYAxis( false ); + redraw = true; + } else if ( e.key.keysym.sym == SDLK_z ) { + _cameras[ _currCam ].viewZAxis( false ); + redraw = true; + } + } + } + } + + return redraw; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::drawWorldAxis() const { + // NOTE: This doesn't GUARANTEE that it's being drawn in the correct space + // It assumes that the modelview matrix is the camera matrix + glPushAttrib( GL_LINE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT ); + glDisable( GL_LIGHTING ); + glDisable( GL_DEPTH_TEST ); + glLineWidth( 2.0f ); + const float AXIS_SCALE = 4.f; + glBegin( GL_LINES ); + glColor3f( 1.f, 0.f, 0.f ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( AXIS_SCALE, 0.f, 0.f ); + glColor3f( 0.f, 1.f, 0.f ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( 0.f, AXIS_SCALE, 0.f ); + glColor3f( 0.f, 0.f, 1.f ); + glVertex3f( 0.f, 0.f, 0.f ); + glVertex3f( 0.f, 0.f, AXIS_SCALE ); + glEnd(); + glPopAttrib(); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::offsetTime( float delta ) { + setTime( _viewTime + delta ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::setBGColor( float r, float g, float b ) { + _bgColor.set( r, g, b ); + glClearColor( r, g, b, 1.f ); + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::setFixedStep( float stepSize ) { + _stepSize = stepSize; + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::initLighting() { + glEnable( GL_LIGHTING ); + for ( size_t i = 0; i < _lights.size(); ++i ) { + _lights[i].initGL( (int) i, SceneGraph::GLLight::CAMERA ); + } + } + + /////////////////////////////////////////////////////////////////////////// + + void GLViewer::setDumpPath( const std::string & path ) { + std::string fullpath; + os::path::absPath( path, fullpath ); + if ( ! os::path::exists( fullpath ) ) { + if ( ! os::makedirs( fullpath ) ) { + logger << Logger::WARN_MSG << "Unable to make path for dumping: " << fullpath << "\n"; + _validDumpPath = false; + return; + } + } + logger << Logger::INFO_MSG << "Dumping png to: " << fullpath << "\n"; + _dumpPath = path; + size_t pos = path.rfind( os::path::pathSep() ); + if ( pos != path.size() - 1 ) { + _dumpPath += os::path::pathSep(); + } + } + + /////////////////////////////////////////////////////////////////////////// + + } // namespace Vis +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/GLViewer.h b/src/Menge/MengeCore/viewer/GLViewer.h new file mode 100644 index 00000000..6b44c875 --- /dev/null +++ b/src/Menge/MengeCore/viewer/GLViewer.h @@ -0,0 +1,441 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file GLViewer.h + * @brief Specification for an OpenGL based 3D viewer. + * + * Can draw a SceneGraph GLScene, perform view + * manipulation and overlay text on the scene. + */ + +#ifndef __GLVIEWER_H__ +#define __GLVIEWER_H__ + +#include "SDL/SDL.h" +#include +#include + +#include "CoreConfig.h" +#include "GLCamera.h" +#include "GLGroundPlane.h" +#include "GLScene.h" +#include "Profiler.h" +#include "ScreenGrab.h" + +namespace Menge { + + // Forward declarations + class Image; + + /*! + * @namespace Vis + * @brief The namespace containing visualization functionality for the + * pedestrian simulation. + */ + namespace Vis { + + // Forward declarations + class ViewConfig; + class Watermark; + + /*! + * @brief Class for defining an OpenGL Viewer. + */ + class MENGE_API GLViewer { + public: + /*! + * @brief Default constructor based on preferred viewer size. + * + * @param width The width of the view window, in pixels. + * @param height The height of the view window, in pixels. + */ + GLViewer( int width, int height ); + + /*! + * @brief Constructor based on configuration in a ViewConfig instance. + * + * @param cfg A fully specified view configuration. + */ + GLViewer( ViewConfig & cfg ); + + /*! + * @brief Destructor. + */ + ~GLViewer(void); + + /*! + * @brief Runs the main loop -- including advancing the scene + * in time. Exiting this function means the main event + * loop is no longer running. + */ + void run(); + + /*! + * @brief Sets the optional background image to the viewer. + * + * @param imgName A valid path to a valid image to load. + * @returns A boolean reporting success (true) or failure (false). + */ + bool setBGImage( const std::string & imgName ); + + /*! + * @brief Reports if the viewer has a background image. + * + * @returns True if there is a background image, false otherwise. + */ + bool hasBGImage() const { return _bgImg != 0x0; } + + /*! + * @brief Sets the watermark to the viewer. + * + * @param imgName A valid path to a valid image to load. + * @returns A boolean reporting success (true) or failure (false). + */ + bool setWatermark( const std::string & imgName ); + + /*! + * @brief Reports if the viewer has a watermark. + * + * @returns True if there is a watermark, false otherwise. + */ + bool hasWatermark() const { return _waterMark != 0x0; } + + /*! + * @brief Clears the background image from the viewer. + */ + void clearBGImage(); + + /*! + * @brief Initializes the viewer with the given title. + * + * @param title The name displayed at the top of the window. + * @returns True if initialization was successful, false otherwise. + */ + bool initViewer( const std::string & title ); + + /*! + * @brief Resizes the window to the indicated size. + * + * @param w The new width of the viewer window. + * @param h The new height of the viewer window. + */ + void resizeGL( int w, int h ); + + /*! + * @brief Initializes the opengl mechanism. + */ + void initGL(); + + /*! + * @brief Sets the GLScene to be drawn. + * A viewer can only draw a single scene; all drawn + * elements belong either to the GLScene or a GLContext. + * + * @param scene The GLScene to be rendered and temporally advanced. + */ + void setScene( SceneGraph::GLScene * scene ); + + /*! + * @brief Causes the viewer to recognize that a new OpenGL context has been + * created (such as window resizes). + */ + void newGLContext(); + + /*! + * @brief Main drawing function -- draws scene and context as available. + */ + void drawGL(); + + /*! + * @brief Processes a mouse event. + * + * @param e An SDL_Event corresponding with an appropriate SDL mouse event (button up/down, move). + * @returns A boolean indicating if a scene redraw is necessary (true) + * or not (false). + */ + bool handleMouse( SDL_Event & e ); + + /*! + * @brief Processes a keyboard event. + * + * @param e An SDL_Event corresponding with an appropriate SDL keyboard event (key up/down). + * @returns A boolean indicating if a scene redraw is necessary (true) + * or not (false). + */ + bool handleKeyboard( SDL_Event & e ); + + /*! + * @brief Sets whether the world axis is drawn or not. + * + * @param state A boolean controlling whether the world axis is drawn (true) + * or not (false). + */ + void setDrawWorldAxis( bool state ) { _drawWorldAxis = state; } + + /*! + * @brief Reports the state of whether the world axis is drawn or not. + * + * @returns A boolean indicating if the world axis is drawn (true) or not (false). + */ + bool getDrawWorldAxis() const { return _drawWorldAxis; } + + /*! + * @brief Draws a red frame around the viewer, indicating that images + * are being saved. + */ + void drawRecordingFrame() const; + + /*! + * @brief Sets the horizontal field of view for the ith camera. + * + * @param i The index of the camera - index value is NOT checked. + * @param fov The horizontal field of view for the indicated camera. + * Value is not validated. + */ + void setCameraFOV( int i, float fov ) { _cameras[i].setFOV( fov ); } + + /*! + * @brief Sets the distance to the camera's far clipping plane. + * + * @param i The index of the camera - index value is NOT checked. + * @param dist The distance, from the camera, to its far clipping plane. + * Value is not validated. + */ + void setCameraFarPlane( int i, float dist ) { _cameras[i].setFarPlane( dist ); } + + /*! + * @brief Change the scene time by the given offset. + * + * @param delta The amount of time change. Can be negative, but only + * meaningful if the GLScene can support negative time changes. + */ + void offsetTime( float delta ); + /*! + * @brief Sets the current time. + * + * @param t The current time for the viewer and its GLScene. + */ + void setTime( float t ) { _viewTime = t; }; + + /*! + * @brief Sets the view's background color. + * This must be called AFTER the view has been initialized. + * + * @param r The red component of the background color (must be in the range [0, 1]). + * @param g The green component of the background color (must be in the range [0, 1]). + * @param b The blue component of the background color (must be in the range [0, 1]). + */ + void setBGColor( float r, float g, float b ); + + /*! + * @brief Gets a pointer to the ith camera. + * + * @param i The index of the desired camera. The index value + * is not checked. + * @returns A pointer to the ith camera. + */ + SceneGraph::GLCamera * getCamera( int i=0 ) { return &_cameras[i]; } + + /*! + * @brief Sets the simulator to use a fixed time step, with the given value. + * + * @param stepSize The size of the fixed step the viewer should advance + * its GLScene. + */ + void setFixedStep( float stepSize ); + + /*! + * @brief Sets the path for when outputting screen capture images. + * + * @param path The path to which output images should be written. + */ + void setDumpPath( const std::string & path ); + + protected: + /*! + * @brief The various SDL flags which determine the view. + */ + static Uint32 FLAGS; + + //////////////////////////////////////////////////////////////// + // members + + /*! + * @brief The width of the viewer window (in pixels). + */ + int _width; + + /*! + * @brief The height of the viewer window (in pixels). + */ + int _height; + + /*! + * @brief The GLScene to draw. + */ + SceneGraph::GLScene * _scene; + + /*! + * @brief A set of cameras from which to draw the scene. + */ + std::vector< SceneGraph::GLCamera > _cameras; + + /*! + * @brief The index of camera currently being used to draw the scene. + */ + size_t _currCam; + + /*! + * @brief The x-position of the mouse when a + * mouse button was depressed (in screen space). + */ + int _downX; + + /*! + * @brief The y-position of the mouse when a + * mouse button was depressed (in screen space). + */ + int _downY; + + // HUD/UI components + + /*! + * @brief Determines if the GLScene needs to update. + */ + bool _update; + + /*! + * @brief Determines whether a world-aligned axis is drawn + */ + bool _drawWorldAxis; + + /*! + * @brief Determines whether the frame rate is displayed in the viewer. + */ + bool _showFPS; + + /*! + * @brief A timer to determine the displayed frame rate value. + */ + SampleTimer _fpsDisplayTimer; + + /*! + * @brief Controls whether the viewer advances the GLScene (true) or not (false). + */ + bool _pause; + + /*! + * @brief Determines if the viewer should still operate -- as long as it is true, it will + * continue its main loop (@see GLViewer::run). + */ + bool _running; + + /*! + * @brief The current time at which the viewer is running. Modified by calls to GLViewer::setTime and + * GLViewer::offsetTime. + */ + float _viewTime; + + /*! + * @brief The viewer's background color. + */ + Vector3 _bgColor; + + /*! + * @brief The step size for fixed-step simulation. + */ + float _stepSize; + + /*! + * @brief A pointer to the optional background image. + */ + Image * _bgImg; + + /*! + * @brief An optional watermark. + */ + Watermark * _waterMark; + + /*! + * @brief Determines if screen capture images will be output at each time advance. + */ + bool _dumpImages; + + /*! + * @brief Reports if the screen capture output path is valid. + */ + bool _validDumpPath; + + /*! + * @brief The path to the folder in which to write screen capture images. + */ + std::string _dumpPath; + + /*! + * @brief The number of images which have been output. Used for + * labeling the image file names into a sequential order. + */ + size_t _imgCount; + + /*! + * @brief The set of lights to use in rendering. + */ + std::vector< SceneGraph::GLLight > _lights; + + /*! + * @brief Initizlies the OpenGL lighting based on the set of lights. + */ + void initLighting(); + + //////////////////////////////////////////////////////////////// + // methods + + /*! + * @brief Initializes the SDL mechanism for event handling and context creation. + */ + bool initSDL( const std::string & title ); + + /*! + * @brief Draws a simple, three-color world axis at the origin of world space. + */ + void drawWorldAxis() const; + }; + } // namespace Vis +} // namespace Menge +#endif // __GLVIEWER_H__ diff --git a/src/Menge/MengeCore/viewer/NullViewer.cpp b/src/Menge/MengeCore/viewer/NullViewer.cpp new file mode 100644 index 00000000..d6843343 --- /dev/null +++ b/src/Menge/MengeCore/viewer/NullViewer.cpp @@ -0,0 +1,96 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "NullViewer.h" +#include "GLScene.h" + +namespace Menge { + + namespace Vis { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of NullViewer + ///////////////////////////////////////////////////////////////////////////// + + NullViewer::NullViewer(): _scene(0x0), _stepSize(0.1f) { + } + + ///////////////////////////////////////////////////////////////////////////// + + NullViewer::~NullViewer() { + if ( _scene ) { + delete _scene; + } + } + + ///////////////////////////////////////////////////////////////////////////// + + void NullViewer::setScene( SceneGraph::GLScene * scene ) { + if ( _scene ) { + delete _scene; + } + _scene = scene; + } + + /////////////////////////////////////////////////////////////////////////// + + void NullViewer::setFixedStep( float stepSize ) { + _stepSize = stepSize; + } + + ///////////////////////////////////////////////////////////////////////////// + + void NullViewer::run() { + if ( _scene == 0x0 ) return; + float viewTime = 0.f; + float frameLen = 0.f; + _fpsTimer.start(); + while ( true ) { + viewTime += _stepSize; + try { + _scene->updateScene( viewTime ); + _fpsTimer.lap(); + } catch ( SceneGraph::SystemStopException ) { + break; + } + } + std::cout << "Average frame computation time: " << _fpsTimer.average( 0.001f ) << " ms\n"; + _scene->finish(); + } + } // namespace Vis +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/NullViewer.h b/src/Menge/MengeCore/viewer/NullViewer.h new file mode 100644 index 00000000..c4c0637c --- /dev/null +++ b/src/Menge/MengeCore/viewer/NullViewer.h @@ -0,0 +1,120 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file NullViewer.h + * @brief Specification for a do-nothing viewer. This is the + * offline simulator. + */ + +#ifndef __NULL_VIEWER_H__ +#define __NULL_VIEWER_H__ + +#include "CoreConfig.h" +#include "Profiler.h" + +namespace Menge { + + // forward declarations + namespace SceneGraph { + class GLScene; + } + + namespace Vis { + + /*! + * @brief The off-line context for running a simulation. + * + * The NullViewer is a mock viewer, similar to the GLViewer + * It takes a SceneGraph node and repeatedly updates the scene + * However, there is no visualization. It's purpose is simply + * to run the scene. + * + * The POINT of this type of thing is to load up an empty scene + * with a non-trivial system that has some secondary, non-visual + * side effects and simply exercise it. + */ + class MENGE_API NullViewer { + public: + /*! + * @brief Default constructor. + */ + NullViewer(); + + /*! + * @brief Destructor. + */ + ~NullViewer(); + + /*! + * @brief The scene to run. + */ + void setScene( SceneGraph::GLScene * scene ); + + /*! + * @brief The main loop. + */ + void run(); + + /*! + * @brief Sets the simulator to use a fixed time step, with the given value. + * + * @param stepSize The size of the fixed step the viewer should advance + * its GLScene. + */ + void setFixedStep( float stepSize ); + + protected: + /*! + * @brief The GLScene to draw. + */ + SceneGraph::GLScene * _scene; + + /*! + * @brief The step size for fixed-step simulation. + */ + float _stepSize; + + /*! + * @brief Timer for determining computation time. + */ + LapTimer _fpsTimer; + }; + } // namespace Vis +} // namespace Menge +#endif // __NULL_VIEWER_H__ diff --git a/src/Menge/MengeCore/viewer/Profiler.cpp b/src/Menge/MengeCore/viewer/Profiler.cpp new file mode 100644 index 00000000..76253e83 --- /dev/null +++ b/src/Menge/MengeCore/viewer/Profiler.cpp @@ -0,0 +1,441 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Profiler.h" + +#include +#include +#include + +namespace Menge { + + namespace Vis { + + //////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION for Timer + //////////////////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + + __int64 Timer::FREQ = 0; + + //////////////////////////////////////////////////////////////////////////// + + Timer::Timer(): _start(0) { + if ( FREQ == 0 ) { + ::QueryPerformanceFrequency( (LARGE_INTEGER*)&FREQ ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void Timer::start() { + ::QueryPerformanceCounter( (LARGE_INTEGER*) &_start ); + } + + //////////////////////////////////////////////////////////////////////////// + + float Timer::elapsed( float scale ) { + __int64 t; + ::QueryPerformanceCounter( (LARGE_INTEGER*) &t ); + __int64 e = t - _start; + _start = t; + return (float)( e ) / (float)(FREQ) * scale; + } + + //////////////////////////////////////////////////////////////////////////// + + #else + + Timer::Timer() { + } + + //////////////////////////////////////////////////////////////////////////// + + void Timer::start() { + clock_gettime( CLOCK_REALTIME, &_start ); + } + + //////////////////////////////////////////////////////////////////////////// + + float Timer::elapsed( float scale ) { + struct timespec t; + clock_gettime( CLOCK_REALTIME, &t ); + return ( ( t.tv_sec - _start.tv_sec ) + ( t.tv_nsec - _start.tv_nsec ) * 1e-9f ) * scale; + } + + #endif + + //////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION for LapTimer + //////////////////////////////////////////////////////////////////////////// + + LapTimer::LapTimer(): Timer(), _total(0), _lapCount(0) { + } + + //////////////////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + + float LapTimer::lap( float scale ) { + __int64 t; + ::QueryPerformanceCounter( (LARGE_INTEGER*) &t ); + __int64 e = t - _start; + _start = t; + _total += e; + ++_lapCount; + return (float)( e ) / (float)(FREQ) * scale; + } + + //////////////////////////////////////////////////////////////////////////// + + float LapTimer::average( float scale ) { + return (float)_total / (float)_lapCount / (float)(FREQ) * scale ; + } + + //////////////////////////////////////////////////////////////////////////// + + #else + + //////////////////////////////////////////////////////////////////////////// + + float LapTimer::lap( float scale ) { + struct timespec t; + clock_gettime( CLOCK_REALTIME, &t ); + float e = ( t.tv_sec - _start.tv_sec ) + ( t.tv_nsec - _start.tv_nsec ) * 1e-9f; + _start = t; + _total += e; + ++_lapCount; + return e * scale; + } + //////////////////////////////////////////////////////////////////////////// + + float LapTimer::average( float scale ) { + return (float)_total / (float)_lapCount * scale ; + } + + //////////////////////////////////////////////////////////////////////////// + + #endif + + //////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION for SampleTimer + //////////////////////////////////////////////////////////////////////////// + + SampleTimer::SampleTimer( int sampleCount ): Timer(), _totalSamples(sampleCount), _currSample(0), + _total(0), _cached(0.f) {} + + //////////////////////////////////////////////////////////////////////////// + + #ifdef _WIN32 + + float SampleTimer::lap( float scale ) { + __int64 t; + ::QueryPerformanceCounter( (LARGE_INTEGER*) &t ); + _total += t - _start; + ++_currSample; + if ( _currSample == _totalSamples ) { + _cached = (float)_total / ( (float)_totalSamples * (float)FREQ ); + _currSample = 0; + _total = 0; + } + _start = t; + return _cached * scale; + } + + #else + + float SampleTimer::lap( float scale ) { + struct timespec t; + clock_gettime( CLOCK_REALTIME, &t ); + _total += ( t.tv_sec - _start.tv_sec ) + ( t.tv_nsec - _start.tv_nsec ) * 1e-9f; + ++_currSample; + if ( _currSample == _totalSamples ) { + _cached = _total / (float)_totalSamples; + _currSample = 0; + _total = 0; + } + _start = t; + return _cached * scale; + } + + #endif + + //////////////////////////////////////////////////////////////////////////// + + #ifdef TIME_CROWD + + //////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION for Profiler + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Class for storing sets of timers for profiling aspects of + * the simulation. + */ + class Profiler { + /*! + * @brief Pointer for singleton instance. + */ + static Profiler * PROFILER; + + /*! + * @brief Private constructor. + */ + Profiler() {} + + //////////////////////////////////////////////////////////////////////////// + public: + /*! + * @brief Returns a pointer to the singleton instance, creating it as + * necessary. + * + * @returns A pointer to the single instance of profiler + */ + static Profiler * getInstance() { + if ( PROFILER == 0x0 ) { + PROFILER = new Profiler(); + } + return PROFILER; + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Creates a lap timer which uses the given label for display. + * + * @param label The string to display when reporting the profiling + * results. + * @returns The identifier for the created timer. + */ + size_t addTimer( const ::std::string & label ) { + assert( _timers.size() == _dispStrings.size() && "Mis-match in timer and display strings" ); + size_t id = _timers.size(); + _timers.push_back( LapTimer() ); + _dispStrings.push_back( label ); + return id; + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the number of timers + */ + size_t timerCount() const { return _timers.size(); } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Starts the ith timer. + * + * @param i The identifier for the timer. Only checked in debug mode. + */ + void start( size_t i ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::start()" ); + _timers[i].start(); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the time elapsed between this call and the last start for the + * ith timer. + * + * @param i The identifier for the timer. Only checked in debug mode. + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The elapsed time of the ith timer's last call (scaled by the given amount). + */ + float elapsed( size_t i, float scale ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::elapsed()" ); + return _timers[i].elapsed( scale ); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the time elapsed from the previous call to lap() or start() to + * this call for the ith timer. The clock is still "running" and the next + * lap starts. + * + * @param i The identifier for the timer. Only checked in debug mode. + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The time elapsed (for units see "scale"). + */ + float lap( size_t i, float scale ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::lap()" ); + return _timers[i].lap( scale ); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the average lap time across all recorded laps for the ith timer. + * + * @param i The identifier for the timer. Only checked in debug mode. + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The time elapsed (for units see "scale"). + */ + float average( size_t i, float scale ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::average()" ); + return _timers[i].average( scale ); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the number of laps the ith counter has had. + * + * @param i The identifier for the timer. Only checked in debug mode. + * @returns The number of laps. + */ + int laps( size_t i ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::laps()" ); + return _timers[i].laps(); + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Reports the average lap time across all recorded laps for the first "count" timers. + * + * @param count The first count timers' average times will be reported. + * Only checked in debug mode. + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @param averages A pointer to an array of floats sufficiently large to hold + * count values. + */ + void averages( size_t count, float scale, float * averages ) { + assert( count <= _timers.size() && "Timer index outside of valid range in Profiler::averages()" ); + for ( size_t i = 0; i < count; ++i ) { + averages[ i ] = _timers[i].average( scale ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Returns the display string for the given LapTimer. + * + * @param i The index of the desired timer -- only validated in debug mode. + * @returns The display string for the indicated LapTimer. + */ + const ::std::string & displayString( size_t i ) { + assert( i < _timers.size() && "Timer index outside of valid range in Profiler::displayString()" ); + return _dispStrings[ i ]; + } + + private: + /*! + * @brief A vector of timers used in profiling. + */ + ::std::vector< LapTimer > _timers; + + /*! + * @brief A vector of display strings for the timers. + */ + ::std::vector< ::std::string > _dispStrings; + }; + + Profiler * Profiler::PROFILER = 0x0; + } // namespace Vis + + //////////////////////////////////////////////////////////////////////////// + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + float SCALE = 1000.0f; + std::string SCALE_LABEL = " ms"; + +#endif + + //////////////////////////////////////////////////////////////////////////// + + size_t addTimer( const std::string & displayString ) { + return Vis::Profiler::getInstance()->addTimer( displayString ); + } + + //////////////////////////////////////////////////////////////////////////// + + void startTimer( size_t index ) { + Vis::Profiler::getInstance()->start( index ); + } + + //////////////////////////////////////////////////////////////////////////// + + void stopTimer( size_t index ) { + Vis::Profiler::getInstance()->lap( index, SCALE ); + } + + //////////////////////////////////////////////////////////////////////////// + + void lapTimer( size_t index ) { + Vis::Profiler::getInstance()->lap( index, SCALE ); + } + + //////////////////////////////////////////////////////////////////////////// + + float averageTime( size_t index ) { + Vis::Profiler * pro = Vis::Profiler::getInstance(); + return pro->average( index, SCALE ); + } + + //////////////////////////////////////////////////////////////////////////// + + void printAverages() { + Vis::Profiler* profiler = Vis::Profiler::getInstance(); + const size_t count = profiler->timerCount(); + for ( size_t i = 0; i < count; ++i ) { + float time = profiler->average( i, SCALE ); + int laps = profiler->laps( i ); + ::std::cout << profiler->displayString( i ) << " (avg): " << time << SCALE_LABEL << " in " << laps << " laps\n"; + } + } + + //////////////////////////////////////////////////////////////////////////// + + void setUnits( float scale, const std::string & unitString ) { + SCALE = scale; + SCALE_LABEL = unitString; + } + + #endif // TIME_CROWD +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/Profiler.h b/src/Menge/MengeCore/viewer/Profiler.h new file mode 100644 index 00000000..2a35a3b4 --- /dev/null +++ b/src/Menge/MengeCore/viewer/Profiler.h @@ -0,0 +1,287 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Profiler.h + * @brief Functionality for timing and profiling the program + */ + +#ifndef __PROFILER_H__ +#define __PROFILER_H__ + +#define TIME_CROWD +#include + +#ifdef _WIN32 +#include "windows.h" +#else // _WIN32 +#include +#include "include/macros.h" +#endif // _WIN32 + +namespace Menge { + + namespace Vis { + /*! + * @brief Basic timer. + */ + class Timer { + public: + /*! + * @brief Default constructor. + */ + Timer(); + + /*! + * @brief Starts the timer running. + */ + void start(); + + /*! + * @brief Reports the time elapsed between this call and the last start. + * + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The elapsed time of the timer's last call (scaled by the given amount). + */ + float elapsed( float scale ); + + protected: + #ifdef _WIN32 + /*! + * @brief The computer's clock frequency - used for converting cycles to seconds + */ + static __int64 FREQ; + + /*! + * @brief The time (in clock cycles) at which the timer was started. + */ + __int64 _start; + + #else // _WIN32 + /*! + * @brief The time (in clock cycles) at which the timer was started. + */ + struct timespec _start; + + #endif // _WIN32 + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Lap timer. A timer which supports "laps" + * i.e., single calls which measure from the last "tick" + * to this tick. + */ + class LapTimer: public Timer { + public: + /*! + * @brief Default constructor + */ + LapTimer(); + + /*! + * @brief Reports the time elapsed from the previous call to lap() or start() to + * this call. The clock is still "running" and the next lap starts. + * + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The time elapsed (for units see "scale"). + */ + float lap( float scale=1.f ); + + /*! + * @brief Reports the average lap time across all recorded laps. + * + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The time elapsed (for units see "scale"). + */ + float average( float scale=1.f ); + + /*! + * @brief Reports the number of calls to laps. + */ + inline int laps() const { return _lapCount; } + + protected: + #ifdef _WIN32 + /*! + * @brief The total accrued time of timed intervals (in cycles). + */ + __int64 _total; + #else // _WIN32 + /*! + * @brief The total accrued time of timed intervals (in seconds). + */ + double _total; + #endif // _WIN32 + + /*! + * @brief The total number of calls to lap() + */ + int _lapCount; + }; + + /////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A timer which uses a cache of values to only update its values + * every N calls to lap/elapsed. Useful for displaying frame rate. + */ + class SampleTimer: public Timer { + public: + /*! + * @brief Constructor. + * + * @param sampleCount The number of repeated calls to lap to cause the + * timer to report a new, average value. + */ + SampleTimer( int sampleCount ); + + /*! + * @brief Reports the average elapsed time of the last N calls to lap + * + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @returns The time elapsed (for units see "scale"). + */ + float lap( float scale=1.f ); + + protected: + /*! + * @brief The number of samples to compute the average over + */ + int _totalSamples; + + /*! + * @brief The curren total number of calls to lap. + */ + int _currSample; + + #ifdef _WIN32 + /*! + * @brief The current accrual of time for the current cache (in cycles). + */ + __int64 _total; + #else // _WIN32 + /*! + * @brief The current accrual of time for the current cache (in seconds). + */ + float _total; + #endif // _WIN32 + + /*! + * @brief The most recently defined elapsed lap time. + */ + float _cached; + }; + + } // namespace Vis + + #ifdef TIME_CROWD + + /*! + * @brief Creates a lap timer which uses the given label for display. + * + * @param displayString The string to display when reporting the profiling + * results. + * @returns The identifier for the created timer. + */ + size_t addTimer( const std::string & displayString ); + + /*! + * @brief Starts the timer with the given identifier. + * + * @param index The timer identifier supplied by addTimer + */ + void startTimer( size_t index ); + + /*! + * @brief Stops the timer with the given identifier. + * + * @param index The timer identifier supplied by addTimer + */ + void stopTimer( size_t index ); + + /*! + * @brief Lap the ith timer + * + * @param index The timer identifier supplied by addTimer + */ + void lapTimer( size_t index ); + + /*! + * @brief Reports the average time of the ith timer + * + * @param index The timer identifier supplied by addTimer + * @returns The average time of all laps. + */ + float averageTime( size_t index ); + + /*! + * @brief Prints the average times for all timers, displayed with the + * accompanying messages and set units. + */ + void printAverages(); + + /*! + * @brief Sets the internal units of the profiler. + * + * @param scale The scale of the units to report the elapsed time in. + * e.g., 1.0 --> seconds, 0.001 -->, 1e-6 --> microseconds. + * @param unitString The units which accompany the given scale -- for printing purposes. + */ + void setUnits( float scale, const std::string & unitString ); + + #else // not defined TIME_CROWD + + #define addTimer( displayString ) (0) + #define startTimer( index ) + #define stopTimer( index ) + #define lapTimer( index ) + #define averageTime( index ) + #define printAverages() + #define setUnits( scale, unitString ) + + #endif // TIME_CROWD + +} // namespace Menge + +#endif // __PROFILER_H__ diff --git a/src/Menge/MengeCore/viewer/ScreenGrab.cpp b/src/Menge/MengeCore/viewer/ScreenGrab.cpp new file mode 100644 index 00000000..4c08598a --- /dev/null +++ b/src/Menge/MengeCore/viewer/ScreenGrab.cpp @@ -0,0 +1,103 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ScreenGrab.h" +#include "Logger.h" +#include "png.h" +#ifdef _WIN32 // only supported under windows +#include "windows.h" +#endif +#include +#include + +namespace Menge { + + bool snapshotPNG(int width, int height, const char* path) { + static int oldHeight = 0; + static int oldWidth = 0; + static GLubyte ** rows = 0x0; + static GLubyte *image = 0x0; + if ( oldHeight != height || oldWidth != width ) { + oldHeight = height; + oldWidth = width; + if ( rows ) { + delete [] rows; + delete [] image; + } + image = new GLubyte[ width * height * 3 ]; + // Set the pointers + rows = new GLubyte *[height]; + const int rowSize = width * 3; + for ( int r = height - 1; r >= 0; --r ) { + rows[ height - r - 1 ] = image + r * rowSize; + } + } + FILE *fp; + static png_structp png_ptr; + static png_infop info_ptr; + #ifdef _WIN32 + fopen_s( &fp, path, "wb" ); + #else + fp = fopen( path, "wb" ); + #endif + if ( fp == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to write image " << path << "\n"; + return false; + } + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + png_init_io(png_ptr, fp); + + //png_set_compression_level(png_ptr, PNGWRITER_DEFAULT_COMPRESSION); + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_write_info(png_ptr, info_ptr); + + // Acquire the image + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, image); + + png_write_image(png_ptr, rows ); + png_write_end(png_ptr, info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return true; + } + +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/ScreenGrab.h b/src/Menge/MengeCore/viewer/ScreenGrab.h new file mode 100644 index 00000000..c151885f --- /dev/null +++ b/src/Menge/MengeCore/viewer/ScreenGrab.h @@ -0,0 +1,60 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ScreenGrab.h + * @brief Functionality for capturing screen grabs to the file system. + */ + +#ifndef __SCREENGRAB_H__ +#define __SCREENGRAB_H__ + +namespace Menge { + + /*! + * @brief Function to create a png from the current screenbuffer + * + * @param windowWidth the current width of the Menge window + * @param windowHeight the current height of the Menge windiw + * @param filename string representation of the target filename. + * + * @returns whether or not the output was successful + */ + bool snapshotPNG(int windowWidth, int windowHeight, const char* filename); +} // namespace Menge +#endif // __SCREENGRAB_H__ \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/ViewConfig.cpp b/src/Menge/MengeCore/viewer/ViewConfig.cpp new file mode 100644 index 00000000..65a18c5f --- /dev/null +++ b/src/Menge/MengeCore/viewer/ViewConfig.cpp @@ -0,0 +1,420 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ViewConfig.h" +#include "Watermark.h" +#include +#include +#include "tinyxml/tinyxml.h" +#include "os.h" + +namespace Menge { + + namespace Vis { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ViewConfig helpers + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Streaming output operator to display camera specification. + * + * @param out The output stream to which to write the view configuration. + * @param camParam The camera parameters to convert to a string. + * @returns The output stream. + */ + Logger & operator<< ( Logger & out, const CameraParam & camParam ) { + out << "Camera - Pos: ( " << camParam._posX << ", " << camParam._posY << ", " << camParam._posZ << " )"; + out << ", Tgt: ( " << camParam._tgtX << ", " << camParam._tgtY << ", " << camParam._tgtZ << " )"; + out << ", Planes: [ " << camParam._nearPlane << ", " << camParam._farPlane << " ]"; + out << ", fov: " << camParam._fov; + return out; + } + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Streaming output operator to display light specification. + * + * @param out The output stream to which to write the view configuration. + * @param lightParam The light parameters to convert to a string. + * @returns The output stream. + */ + Logger & operator<< ( Logger & out, const LightParam & lightParam ) { + out << "Light - Pos: ( " << lightParam._x << ", " << lightParam._y << ", " << lightParam._z << " )"; + out << ", Color: ( " << lightParam._r << ", " << lightParam._g << ", " << lightParam._b << " )"; + return out; + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of ViewConfig + //////////////////////////////////////////////////////////////////////////// + + ViewConfig::ViewConfig():_viewFldr("."), _waterMark(0x0) { + setDefaults(); + } + + //////////////////////////////////////////////////////////////////////////// + + ViewConfig::~ViewConfig() { + if ( _waterMark ) delete _waterMark; + } + + //////////////////////////////////////////////////////////////////////////// + + bool ViewConfig::readXML( const std::string & fileName ) { + TiXmlDocument xml( fileName ); + bool loadOkay = xml.LoadFile(); + + if ( !loadOkay ) { // load xml file + logger << Logger::ERR_MSG << "Could not load view configuration xml (" << fileName << ") due to xml syntax errors.\n"; + logger << "\t" << xml.ErrorDesc(); + return false; + } + + TiXmlElement* rootNode = xml.RootElement(); + if( ! rootNode ) { + logger << Logger::ERR_MSG << "View configuration (" << fileName << ") does not contain a root element."; + return false; + } + + if( rootNode->ValueStr () != "View" ) { + logger << Logger::ERR_MSG << "View configuration (" << fileName << ")'s root element is not \"View\"."; + return false; + } + + std::string absPath; + os::path::absPath( fileName, absPath ); + std::string junk; + os::path::split( absPath, _viewFldr, junk ); + logger.line(); + logger << Logger::INFO_MSG << "View root: " << _viewFldr << "\n"; + + bool valid = true; + + // View parameters + double d; + int i; + + if ( !rootNode->Attribute( "width", &i ) ) { + logger << Logger::ERR_MSG << "\tView element on line " << rootNode->Row() << " must specify width parameter."; + valid = false; + } else { + _width = i; + } + + if ( !rootNode->Attribute( "height", &i ) ) { + logger << Logger::ERR_MSG << "\tView element on line " << rootNode->Row() << " must specify height parameter."; + valid = false; + } else { + _height = i; + } + + const char * name = rootNode->Attribute( "bgImg" ); + if ( name != 0x0 ) { + std::string tmp = os::path::join( 2, _viewFldr.c_str(), name ); + os::path::absPath( tmp, _bgImg ); + } + + _camSpecs.clear(); + _lightSpecs.clear(); + TiXmlElement* child; + for( child = rootNode->FirstChildElement(); child; child = child->NextSiblingElement()) { + if ( child->ValueStr() == "Camera" ) { + CameraParam cam; + // position + if ( !child->Attribute( "xpos", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"xpos\" parameter."; + valid = false; + } else { + cam._posX = (float)d; + } + if ( !child->Attribute( "ypos", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"ypos\" parameter."; + valid = false; + } else { + cam._posY = (float)d; + } + if ( !child->Attribute( "zpos", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"zpos\" parameter."; + valid = false; + } else { + cam._posZ = (float)d; + } + // target position + if ( !child->Attribute( "xtgt", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"xtgt\" parameter."; + valid = false; + } else { + cam._tgtX = (float)d; + } + if ( !child->Attribute( "ytgt", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"ytgt\" parameter."; + valid = false; + } else { + cam._tgtY = (float)d; + } + if ( !child->Attribute( "ztgt", &d ) ) { + logger << Logger::ERR_MSG << "\tCamera element on line " << child->Row() << " must specify \"ztgt\" parameter."; + valid = false; + } else { + cam._tgtZ = (float)d; + } + // clipping planes + if ( child->Attribute( "near", &d ) ) { + cam._nearPlane = (float)d; + } + if ( child->Attribute( "far", &d ) ) { + cam._farPlane = (float)d; + } + // projection + float fov = 45.f; + if ( child->Attribute( "fov", &d ) ) { + fov = (float) d; + } + if ( fov == 0.f ) { + cam._projType = SceneGraph::GLCamera::ORTHO; + cam._fov = fov; + } else { + cam._projType = SceneGraph::GLCamera::PERSP; + cam._fov = fov; + } + // orthographic zoom + if ( child->Attribute( "orthoScale", &d ) ) { + cam._orthoScale = (float)d; + } + if ( valid ) { + _camSpecs.push_back( cam ); + } + + } else if ( child->ValueStr() == "Light" ) { + LightParam light; + // position + if ( !child->Attribute( "x", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"x\" parameter."; + valid = false; + } else { + light._x = (float)d; + } + if ( !child->Attribute( "y", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"y\" parameter."; + valid = false; + } else { + light._y = (float)d; + } + if ( !child->Attribute( "z", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"z\" parameter."; + valid = false; + } else { + light._z = (float)d; + } + // type + const char * type = child->Attribute( "type" ); + if ( type != 0x0 ) { + std::string typeStr( type ); + if ( typeStr == "point" ) { + light._w = 1.f; + } else if ( typeStr == "directional" ) { + light._w = 0.f; + } else { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"type\" parameter as \"point\" or \"directional\"."; + valid = false; + } + } else { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"type\" parameter as \"point\" or \"directional\"."; + valid = false; + } + // space + type = child->Attribute( "space" ); + if ( type != 0x0 ) { + std::string typeStr( type ); + if ( typeStr == "world" ) { + light._space = SceneGraph::GLLight::WORLD; + } else if ( typeStr == "camera" ) { + light._space = SceneGraph::GLLight::CAMERA; + } else { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"space\" parameter as \"world\" or \"camera\"."; + valid = false; + } + } else { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"space\" parameter as \"world\" or \"camera\"."; + valid = false; + } + // color + if ( !child->Attribute( "diffR", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"diffR\" parameter."; + valid = false; + } else { + light._r = (float)d; + } + if ( !child->Attribute( "diffG", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"diffG\" parameter."; + valid = false; + } else { + light._g = (float)d; + } + if ( !child->Attribute( "diffB", &d ) ) { + logger << Logger::ERR_MSG << "\tLight element on line " << child->Row() << " must specify \"diffB\" parameter."; + valid = false; + } else { + light._b = (float)d; + } + if ( child->Attribute( "diffA", &d ) ) { + light._a = (float)d; + } + if ( valid ) { + _lightSpecs.push_back( light ); + } + } else if ( child->ValueStr() == "Font" ) { + // font name + const char * name = child->Attribute( "name" ); + if ( name != 0x0 ) { + _fontName = name; + } + double d; + + if ( child->Attribute( "r", &d ) ) { + _fontColor[0] = (float)d; + } + + if ( child->Attribute( "g", &d ) ) { + _fontColor[1] = (float)d; + } + + if ( child->Attribute( "b", &d ) ) { + _fontColor[2] = (float)d; + } + + if ( child->Attribute( "a", &d ) ) { + _fontColor[3] = (float)d; + } + } else if ( child->ValueStr() == "Watermark" ) { + _waterMark = parseWatermark( child, _viewFldr ); + } + } + if ( valid && _camSpecs.size() == 0 ) { + logger << Logger::WARN_MSG << "No cameras specified; using default!"; + _camSpecs.push_back( CameraParam() ); + } + return valid; + } + + //////////////////////////////////////////////////////////////////////////// + + void ViewConfig::setDefaults() { + _width = 640; + _height = 480; + _camSpecs.clear(); + _camSpecs.push_back( CameraParam() ); + _lightSpecs.clear(); + _bgImg = ""; + _fontName = "arial.ttf"; + _fontColor[0] = _fontColor[1] = _fontColor[2] = 1.f; + _fontColor[3] = 0.75f; + } + + //////////////////////////////////////////////////////////////////////////// + + void ViewConfig::setCamera( SceneGraph::GLCamera &camera, size_t i ) const { + // TODO: set multiple cameras + const CameraParam & cfg = _camSpecs[i]; + camera.setPosition( cfg._posX, cfg._posY, cfg._posZ ); + camera.setTarget( cfg._tgtX, cfg._tgtY, cfg._tgtZ ); + camera.setFarPlane( cfg._farPlane ); + camera.setNearPlane( cfg._nearPlane ); + if ( cfg._projType == SceneGraph::GLCamera::ORTHO ) { + camera.setOrtho( cfg._orthoScale ); + } else { + camera.setFOV( cfg._fov ); + camera.setPersp(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void ViewConfig::setCameras( std::vector< SceneGraph::GLCamera > & cameras ) const { + cameras.clear(); + for ( size_t i = 0; i < _camSpecs.size(); ++i ) { + SceneGraph::GLCamera cam; + setCamera( cam, i ); + cameras.push_back( cam ); + } + } + + //////////////////////////////////////////////////////////////////////////// + + void ViewConfig::setLight( SceneGraph::GLLight &light, size_t i ) const { + // TODO: set multiple cameras + const LightParam & cfg = _lightSpecs[i]; + light.setColor( cfg._r, cfg._g, cfg._b, cfg._a ); + light.setPosition( cfg._x, cfg._y, cfg._z, cfg._w ); + light.setSpace( cfg._space ); + } + + //////////////////////////////////////////////////////////////////////////// + + void ViewConfig::setLights( std::vector< SceneGraph::GLLight > & lights ) const { + lights.clear(); + for ( size_t i = 0; i < _lightSpecs.size(); ++i ) { + SceneGraph::GLLight light; + setLight( light, i ); + lights.push_back( light ); + } + } + + } // namespace Vis + //////////////////////////////////////////////////////////////////////////// + + Logger & operator<< ( Logger & out, const Vis::ViewConfig & cfg ) { + out << "View configuration:"; + out << "\n\twidth: " << cfg._width; + out << "\n\theight: " << cfg._height; + for ( size_t i = 0; i < cfg._camSpecs.size(); ++i ) { + out << "\n\t" << i << " " << cfg._camSpecs[i]; + } + for ( size_t i = 0; i < cfg._lightSpecs.size(); ++i ) { + out << "\n\t" << i << " " << cfg._lightSpecs[i]; + } + out << "\n\tBackground image: " << cfg._bgImg; + if ( cfg._waterMark ) { + out << "\n\tWatermark image: " << cfg._waterMark->getFilename() ; + } + + return out; + } +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/ViewConfig.h b/src/Menge/MengeCore/viewer/ViewConfig.h new file mode 100644 index 00000000..2bd0eba2 --- /dev/null +++ b/src/Menge/MengeCore/viewer/ViewConfig.h @@ -0,0 +1,321 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ViewConfig.h + * @brief Specification for parsing the view configuration file. + */ + +#ifndef __VIEW_CONFIG_H__ +#define __VIEW_CONFIG_H__ + +#include +#include +#include "CoreConfig.h" +#include "GLCamera.h" +#include "GLLight.h" +#include "Logger.h" + +namespace Menge { + + namespace Vis { + + // forward declarations + class Watermark; + + /*! + * @brief A set of parameters specifying a single camera. + */ + class CameraParam { + public: + /*! + * @brief Default constructor. + */ + CameraParam() { + _posX = _posY = _tgtX = _tgtY = _tgtZ = 0.0f; + _posZ = 10.f; + _farPlane = 200.f; + _nearPlane = 0.01f; + _orthoScale = 1.f; + _fov = 0.f; + _projType = SceneGraph::GLCamera::ORTHO; + } + + /*! + * @brief Camera x-position in world space. + */ + float _posX; + + /*! + * @brief Camera y-position in world space. + */ + float _posY; + + /*! + * @brief Camera z-position in world space. + */ + float _posZ; + + /*! + * @brief Camera's target x-position in world space. + */ + float _tgtX; + + /*! + * @brief Camera's target y-position in world space. + */ + float _tgtY; + + /*! + * @brief Camera's target z-position in world space. + */ + float _tgtZ; + + /*! + * @brief Distance to camera's far plane. + */ + float _farPlane; + + /*! + * @brief Distance to camera's near plane. + */ + float _nearPlane; + + /*! + * @brief The "scale" factor applid to the camera in orthographic view. + */ + float _orthoScale; + + /*! + * @brief The camera's horizontal field of view (in degrees). + */ + float _fov; + + /*! + * @brief The camera's projection type (perspective or orthographic). + * + * @see SceneGraph::GLCamera + */ + SceneGraph::GLCamera::CamEnum _projType; + }; + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief A set of parameters specifying a single light + */ + class LightParam { + public: + /*! + * @brief Default constructor. + */ + LightParam() { + _r = _g = _b = 1.f; + _x = _y = _z = 1.f; + _w = 0.f; // 0 --> directional, 1 --> point + } + + /*! + * @brief The red channel of the light's diffuse color. + */ + float _r; + + /*! + * @brief The green channel of the light's diffuse color. + */ + float _g; + + /*! + * @brief The blue channel of the light's diffuse color. + */ + float _b; + + /*! + * @brief The alpha channel of the lights' diffuse color. + */ + float _a; + + /*! + * @brief The x-value of the light position + */ + float _x; + + /*! + * @brief The y-value of the light position + */ + float _y; + + /*! + * @brief The z-value of the light position + */ + float _z; + + /*! + * @brief The w-value of the light position. Determines if the light + * Is a point or directional light. + */ + float _w; + + /*! + * @brief The space in which the light lives. + */ + SceneGraph::GLLight::LightSpace _space; + }; + + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The specification of an OpenGL GLViewer for a scene + * + * @see GLViewer + */ + class MENGE_API ViewConfig { + public: + /*! + * @brief Default constructor. + */ + ViewConfig(); + + /*! + * @brief Destructor. + */ + ~ViewConfig(); + + /*! + * @brief Parses the XML configuration file. + * + * @param fileName The name of the view configuration file to parse. + * @returns A boolean reporting success (true) or failure (false). + */ + bool readXML( const std::string & fileName ); + + /*! + * @brief Sets the view configuration to a set of default values. + */ + void setDefaults(); + + /*! + * @brief Set the camera properties based on the configuration + * + * @param camera The camera to set + * @param i The index of the camera + */ + void setCamera( SceneGraph::GLCamera & camera, size_t i=0 ) const; + + /*! + * @brief Sets the vector of cameras based on the camera specifications + * + * @param cameras A vector to populate with cameras. Any pre-existing cameras + * will be deleted. + */ + void setCameras( std::vector< SceneGraph::GLCamera > & cameras ) const; + + /*! + * @brief Set the light properties based on the configuration + * + * @param light The light to set + * @param i The index of the light specification to apply + */ + void setLight( SceneGraph::GLLight & light, size_t i=0 ) const; + + /*! + * @brief Sets the vector of lights based on the light specifications + * + * @param lights A vector to populate with lights. Any pre-existing lights + * will be deleted. + */ + void setLights( std::vector< SceneGraph::GLLight > & lights ) const; + + /*! + * @brief The folder the view configuration file is located in. + */ + std::string _viewFldr; + + /*! + * @brief Width of viewport (in pixels). + */ + int _width; + + /*! + * @brief Height of viewport (in pixels). + */ + int _height; + + /*! + * @brief The name of the background image to use. + */ + std::string _bgImg; + + /*! + * @brief The optional watermark. + */ + Watermark * _waterMark; + + /*! + * @brief Font name. + */ + std::string _fontName; + + /*! + * @brief Default font color. + */ + float _fontColor[4]; + + /*! + * @brief The set of cameras for the configuration + */ + std::vector< CameraParam > _camSpecs; + + /*! + * @brief The set of cameras for the configuration + */ + std::vector< LightParam > _lightSpecs; + }; + } // namespace Vis + + /*! + * @brief Streaming output operator to display configuration specification. + * + * @param out The output stream to which to write the view configuration. + * @param cfg The configuration to convert to a string. + * @returns The output stream. + */ + MENGE_API Logger & operator<< ( Logger & out, const Vis::ViewConfig & cfg ); +} // namespace Menge + +#endif // __VIEW_CONFIG_H__ diff --git a/src/Menge/MengeCore/viewer/Watermark.cpp b/src/Menge/MengeCore/viewer/Watermark.cpp new file mode 100644 index 00000000..210f674b --- /dev/null +++ b/src/Menge/MengeCore/viewer/Watermark.cpp @@ -0,0 +1,258 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "Watermark.h" + +#ifdef _MSC_VER +#include "windows.h" +#endif +#include "GL/gl.h" + +#include "Logger.h" +#include "tinyxml.h" +#include "os.h" +#include "image.h" +#include "Utils.h" + +namespace Menge { + + namespace Vis { + + //////////////////////////////////////////////////////////////////////////// + // Implementation of Watermark helper function + //////////////////////////////////////////////////////////////////////////// + + /*! + * @brief helper function to convert a string to water mark alignment + * + * @param s the string representing the alignment + * @returns a WatermarkAlign corresponding to the given string + */ + WatermarkAlign getAlignment( std::string s ) { + WatermarkAlign align = NO_ALIGN; + if ( s == "centered" ) { + align = CENTERED; + } else if ( s == "bottom_left" ) { + align = BOTTOM_LEFT; + } else if ( s == "bottom_right" ) { + align = BOTTOM_RIGHT; + } else if ( s == "top_left" ) { + align = TOP_LEFT; + } else if ( s == "top_right" ) { + align = TOP_RIGHT; + } + return align; + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of Watermark + //////////////////////////////////////////////////////////////////////////// + + Watermark::Watermark(): _fileName(""), _img(0x0), _alignment(BOTTOM_RIGHT), _opacity(0.5f), _scale(0.5f) { + } + + //////////////////////////////////////////////////////////////////////////// + + Watermark::~Watermark() { + if ( _img ) delete _img; + } + + //////////////////////////////////////////////////////////////////////////// + + void Watermark::drawGL( float w, float h ) const { + float iW = _img->getWidth() * _scale; + float iH = _img->getHeight() * _scale; + + float min_x, max_x, min_y, max_y; + float u = 1.f, v = 1.f; + if ( _alignment == CENTERED ) { + float midX = w * 0.5f; + iW *= 0.5f; + float midY = h * 0.5f; + iH *= 0.5f; + min_x = midX - iW; + max_x = midX + iW; + min_y = midY - iH; + max_y = midY + iH; + } else if ( _alignment == BOTTOM_LEFT ) { + min_x = min_y = 0.f; + max_x = iW; + max_y = iH; + } else if ( _alignment == BOTTOM_RIGHT ) { + min_y = 0.f; + max_y = iH; + min_x = w - iW; + max_x = w; + } else if ( _alignment == TOP_LEFT ) { + min_x = 0.f; + max_x = iW; + min_y = h - iH; + max_y = h; + } else if ( _alignment == TOP_RIGHT ) { + min_x = w - iW; + max_x = w; + min_y = h - iH; + max_y = h; + } + + // set up rendering + glPushAttrib( GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT ); + glDisable( GL_LIGHTING ); + glDisable( GL_DEPTH_TEST ); + glDepthMask( GL_FALSE ); + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, w, 0.0, h, -1.0f, 1.0f ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + _img->bind(); + glColor4f( 1.f, 1.f, 1.f, _opacity ); + if ( _opacity < 1.f ) { + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; + } + glBegin( GL_QUADS ); + glTexCoord2f( 0.f, v ); + glVertex3f( min_x, min_y, 0.f ); + glTexCoord2f( u, v ); + glVertex3f( max_x, min_y, 0.f ); + glTexCoord2f( u, 0.f ); + glVertex3f( max_x, max_y, 0.f ); + glTexCoord2f( 0.f, 0.f ); + glVertex3f( min_x, max_y, 0.f ); + glEnd(); + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopAttrib(); + } + + //////////////////////////////////////////////////////////////////////////// + // Implementation of Watermark + //////////////////////////////////////////////////////////////////////////// + + Watermark * parseWatermark( TiXmlElement * node, const std::string & viewFldr ) { + // collect parameters + // Filename - make sure it exists + Watermark * mark = 0x0; + const char * fNameCStr = node->Attribute( "file_name" ); + Image * img = 0x0; + if ( fNameCStr ) { + std::string fName; + std::string path = os::path::join( 2, viewFldr.c_str(), fNameCStr ); + os::path::absPath( path, fName ); + if ( ! os::path::exists( fName ) ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " references a file that doesn't exist: " << fName << ". No watermark will be created."; + return mark; + } + img = loadImage( fName ); + if ( !img ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " references a file that couldn't be loaded as an image: " << fName << ". No watermark will be created."; + return mark; + } + } else { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " is missing the \"file_name\" attribute. No watermark will be created."; + return mark; + } + + // alignment + WatermarkAlign align = BOTTOM_RIGHT; + const char * alignCStr = node->Attribute( "alignment" ); + if ( alignCStr ) { + align = getAlignment( std::string( alignCStr ) ); + if ( align == NO_ALIGN ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " has invalid value for the \"alignment\" attribute (" << node->Attribute( "alignment" ) << "). Default value of \"bottom_right\"will be used."; + align = BOTTOM_RIGHT; + } + } else { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " is missing the \"alignment\" attribute. Default will be used."; + } + + // opacity + float opacity = 0.5f; + const char * opacityStr = node->Attribute( "opacity" ); + if ( opacityStr ) { + try { + opacity = toFloat( opacityStr ); + if ( opacity < 0.f ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " has negative \"opacity\" value. Value will be clamped to zero."; + opacity = 0.f; + } else if ( opacity > 1.f ) { + logger << Logger::WARN_MSG << "Watermark specification " << node->Row() << " has \"opacity\" value greater than one. Value will be clamped to one."; + opacity = 1.f; + } + } catch ( UtilException ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " has a badly formatted value for the \"opacity\" attribute. Default value " << opacity << " will be used."; + } + } else { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " is missing the \"opacity\" attribute. Default value " << opacity << " will be used."; + } + + // scale + float scale = 0.5f; + const char * scaleStr = node->Attribute( "scale" ); + if ( scaleStr ) { + try { + scale = toFloat( scaleStr ); + if ( scale < 0.f ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " has negative \"scale\" value. Value will be clamped to zero."; + scale = 0.f; + } + } catch ( UtilException ) { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " has a badly formatted value for the \"scale\" attribute. Default value " << scale << " will be used."; + } + } else { + logger << Logger::WARN_MSG << "Watermark specification on line " << node->Row() << " is missing the \"scale\" attribute. Default value " << scale << " will be used."; + } + + mark = new Watermark(); + mark->_fileName = fNameCStr; + mark->_img = img; + mark->_alignment = align; + mark->_opacity = opacity; + mark->_scale = scale; + return mark; + } + + } // namespace Vis +} // namespace Menge \ No newline at end of file diff --git a/src/Menge/MengeCore/viewer/Watermark.h b/src/Menge/MengeCore/viewer/Watermark.h new file mode 100644 index 00000000..82c8a8a8 --- /dev/null +++ b/src/Menge/MengeCore/viewer/Watermark.h @@ -0,0 +1,142 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Watermark.h + * @brief Data for controlling a watermark. + */ + +#ifndef __WATER_MARK_H__ +#define __WATER_MARK_H__ + +#include + +// forward declaration +class TiXmlElement; + +namespace Menge { + + class Image; + + namespace Vis { + /*! + * @brief The potential alignment of the watermark. + */ + enum WatermarkAlign { + NO_ALIGN, ///< Undefined alignment. + CENTERED, ///< Center the image in the screen. + BOTTOM_LEFT, ///< Place the image in the bottom-left corner of the screen. + BOTTOM_RIGHT, ///< Place the image in the bottom-right corner of the screen. + TOP_LEFT, ///< Place the image in the top-left corner of the screen. + TOP_RIGHT ///< Place the image in the top-right corner of the screen. + }; + + /*! + * @brief A class for handling the watermark functionality. + * + * A watermark is a semi-transparent image drawn over the top of the scene. + */ + class Watermark { + public: + /*! + * @brief Constructor. + */ + Watermark(); + + /*! + * @brief Destructor. + */ + ~Watermark(); + + /*! + * @brief Returns the file name for the water mark. + */ + const std::string & getFilename() const { return _fileName; } + + /*! + * @brief Draws the watermark to the screen. + * + * @param w The width of the screen (in pixels). + * @param h The height of the screen (in pixels). + */ + void drawGL( float w, float h ) const; + + friend Watermark * parseWatermark( TiXmlElement * node, const std::string & viewFldr ); + + protected: + /*! + * @brief File name of the watermark. + */ + std::string _fileName; + + /*! + * @brief A pointer to the image the watermark uses. + */ + Image * _img; + + /*! + * @brief The alignment of the watermark. + */ + WatermarkAlign _alignment; + + /*! + * @brief The opacity of the watermark. Should be a value + * in the range [0, 1], where 0 is completely transparent + * and 1 is completely opaque. + */ + float _opacity; + + /*! + * @brief The scale of the watermark. + * If the alignment is FULL_SCREEN, this can cause tiling. + */ + float _scale; + }; + + /*! + * @brief Parses a water mark xml specification and returns the corresponding + * instance. + * + * @param node The XML node containing the watermark definition. + * @param viewFldr The path to the view configuration file. + * @returns A pointer to a water mark, if the definition was valid (NULL otherwise). + */ + Watermark * parseWatermark( TiXmlElement * node, const std::string & viewFldr ); + } // namespace Vis +} // namespace Menge +#endif // __WATER_MARK_H__ \ No newline at end of file diff --git a/src/Menge/include/SDL/SDL.h b/src/Menge/include/SDL/SDL.h new file mode 100644 index 00000000..60ac26ce --- /dev/null +++ b/src/Menge/include/SDL/SDL.h @@ -0,0 +1,94 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Main include header for the SDL library */ + +#ifndef _SDL_H +#define _SDL_H + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_audio.h" +#include "SDL_cdrom.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_loadso.h" +#include "SDL_mutex.h" +#include "SDL_rwops.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_video.h" +#include "SDL_version.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/* These are the flags which may be passed to SDL_Init() -- you should + specify the subsystems which you will be using in your application. +*/ +#define SDL_INIT_TIMER 0x00000001 +#define SDL_INIT_AUDIO 0x00000010 +#define SDL_INIT_VIDEO 0x00000020 +#define SDL_INIT_CDROM 0x00000100 +#define SDL_INIT_JOYSTICK 0x00000200 +#define SDL_INIT_NOPARACHUTE 0x00100000 /* Don't catch fatal signals */ +#define SDL_INIT_EVENTTHREAD 0x01000000 /* Not supported on all OS's */ +#define SDL_INIT_EVERYTHING 0x0000FFFF + +/* This function loads the SDL dynamically linked library and initializes + * the subsystems specified by 'flags' (and those satisfying dependencies) + * Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup + * signal handlers for some commonly ignored fatal signals (like SIGSEGV) + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/* This function initializes specific SDL subsystems */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/* This function cleans up specific SDL subsystems */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/* This function returns mask of the specified subsystems which have + been initialized. + If 'flags' is 0, it returns a mask of all initialized subsystems. +*/ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/* This function cleans up all initialized subsystems and unloads the + * dynamically linked library. You should call it upon all exit conditions. + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_H */ diff --git a/src/Menge/include/SDL/SDL_active.h b/src/Menge/include/SDL/SDL_active.h new file mode 100644 index 00000000..2cf474c5 --- /dev/null +++ b/src/Menge/include/SDL/SDL_active.h @@ -0,0 +1,58 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL application focus event handling */ + +#ifndef _SDL_active_h +#define _SDL_active_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The available application states */ +#define SDL_APPMOUSEFOCUS 0x01 /* The app has mouse coverage */ +#define SDL_APPINPUTFOCUS 0x02 /* The app has input focus */ +#define SDL_APPACTIVE 0x04 /* The application is active */ + +/* Function prototypes */ +/* + * This function returns the current state of the application, which is a + * bitwise combination of SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS, and + * SDL_APPACTIVE. If SDL_APPACTIVE is set, then the user is able to + * see your application, otherwise it has been iconified or disabled. + */ +extern DECLSPEC Uint8 SDLCALL SDL_GetAppState(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_active_h */ diff --git a/src/Menge/include/SDL/SDL_audio.h b/src/Menge/include/SDL/SDL_audio.h new file mode 100644 index 00000000..68ec4759 --- /dev/null +++ b/src/Menge/include/SDL/SDL_audio.h @@ -0,0 +1,253 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Access to the raw audio mixing buffer for the SDL library */ + +#ifndef _SDL_audio_h +#define _SDL_audio_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The calculated values in this structure are calculated by SDL_OpenAudio() */ +typedef struct SDL_AudioSpec { + int freq; /* DSP frequency -- samples per second */ + Uint16 format; /* Audio data format */ + Uint8 channels; /* Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /* Audio buffer silence value (calculated) */ + Uint16 samples; /* Audio buffer size in samples (power of 2) */ + Uint16 padding; /* Necessary for some compile environments */ + Uint32 size; /* Audio buffer size in bytes (calculated) */ + /* This function is called when the audio device needs more data. + 'stream' is a pointer to the audio data buffer + 'len' is the length of that buffer in bytes. + Once the callback returns, the buffer will no longer be valid. + Stereo samples are stored in a LRLRLR ordering. + */ + void (SDLCALL *callback)(void *userdata, Uint8 *stream, int len); + void *userdata; +} SDL_AudioSpec; + +/* Audio format flags (defaults to LSB byte order) */ +#define AUDIO_U8 0x0008 /* Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /* Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /* Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /* Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /* As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /* As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB + +/* Native audio byte ordering */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#endif + + +/* A structure to hold a set of audio conversion filters and buffers */ +typedef struct SDL_AudioCVT { + int needed; /* Set to 1 if conversion possible */ + Uint16 src_format; /* Source audio format */ + Uint16 dst_format; /* Target audio format */ + double rate_incr; /* Rate conversion increment */ + Uint8 *buf; /* Buffer to hold entire audio data */ + int len; /* Length of original audio buffer */ + int len_cvt; /* Length of converted audio buffer */ + int len_mult; /* buffer must be len*len_mult big */ + double len_ratio; /* Given len, final size is len*len_ratio */ + void (SDLCALL *filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); + int filter_index; /* Current audio conversion function */ +} SDL_AudioCVT; + + +/* Function prototypes */ + +/* These functions are used internally, and should not be used unless you + * have a specific need to specify the audio driver you want to use. + * You should normally use SDL_Init() or SDL_InitSubSystem(). + */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); + +/* This function fills the given character buffer with the name of the + * current audio driver, and returns a pointer to it if the audio driver has + * been initialized. It returns NULL if no driver has been initialized. + */ +extern DECLSPEC char * SDLCALL SDL_AudioDriverName(char *namebuf, int maxlen); + +/* + * This function opens the audio device with the desired parameters, and + * returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by 'obtained'. If 'obtained' is NULL, the audio + * data passed to the callback function will be guaranteed to be in the + * requested format, and will be automatically converted to the hardware + * audio format if necessary. This function returns -1 if it failed + * to open the audio device, or couldn't set up the audio thread. + * + * When filling in the desired audio spec structure, + * 'desired->freq' should be the desired audio frequency in samples-per-second. + * 'desired->format' should be the desired audio format. + * 'desired->samples' is the desired size of the audio buffer, in samples. + * This number should be a power of two, and may be adjusted by the audio + * driver to a value more suitable for the hardware. Good values seem to + * range between 512 and 8096 inclusive, depending on the application and + * CPU speed. Smaller values yield faster response time, but can lead + * to underflow if the application is doing heavy processing and cannot + * fill the audio buffer in time. A stereo sample consists of both right + * and left channels in LR ordering. + * Note that the number of samples is directly related to time by the + * following formula: ms = (samples*1000)/freq + * 'desired->size' is the size in bytes of the audio buffer, and is + * calculated by SDL_OpenAudio(). + * 'desired->silence' is the value used to set the buffer to silence, + * and is calculated by SDL_OpenAudio(). + * 'desired->callback' should be set to a function that will be called + * when the audio device is ready for more data. It is passed a pointer + * to the audio buffer, and the length in bytes of the audio buffer. + * This function usually runs in a separate thread, and so you should + * protect data structures that it accesses by calling SDL_LockAudio() + * and SDL_UnlockAudio() in your code. + * 'desired->userdata' is passed as the first parameter to your callback + * function. + * + * The audio device starts out playing silence when it's opened, and should + * be enabled for playing by calling SDL_PauseAudio(0) when you are ready + * for your audio callback function to be called. Since the audio driver + * may modify the requested size of the audio buffer, you should allocate + * any local mixing buffers after you open the audio device. + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained); + +/* + * Get the current audio state: + */ +typedef enum { + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_audiostatus; +extern DECLSPEC SDL_audiostatus SDLCALL SDL_GetAudioStatus(void); + +/* + * This function pauses and unpauses the audio callback processing. + * It should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); + +/* + * This function loads a WAVE from the data source, automatically freeing + * that source if 'freesrc' is non-zero. For example, to load a WAVE file, + * you could do: + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); + * + * If this function succeeds, it returns the given SDL_AudioSpec, + * filled with the audio data format of the wave data, and sets + * 'audio_buf' to a malloc()'d buffer containing the audio data, + * and sets 'audio_len' to the length of that audio buffer, in bytes. + * You need to free the audio buffer with SDL_FreeWAV() when you are + * done with it. + * + * This function returns NULL and sets the SDL error message if the + * wave file cannot be opened, uses an unknown data format, or is + * corrupt. Currently raw and MS-ADPCM WAVE files are supported. + */ +extern DECLSPEC SDL_AudioSpec * SDLCALL SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len); + +/* Compatibility convenience function -- loads a WAV from a file */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/* + * This function frees data previously allocated with SDL_LoadWAV_RW() + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 *audio_buf); + +/* + * This function takes a source format and rate and a destination format + * and rate, and initializes the 'cvt' structure with information needed + * by SDL_ConvertAudio() to convert a buffer of audio data from one format + * to the other. + * This function returns 0, or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT *cvt, + Uint16 src_format, Uint8 src_channels, int src_rate, + Uint16 dst_format, Uint8 dst_channels, int dst_rate); + +/* Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), + * created an audio buffer cvt->buf, and filled it with cvt->len bytes of + * audio data in the source format, this function will convert it in-place + * to the desired format. + * The data conversion may expand the size of the audio data, so the buffer + * cvt->buf should be allocated after the cvt structure is initialized by + * SDL_BuildAudioCVT(), and should be cvt->len*cvt->len_mult bytes long. + */ +extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT *cvt); + +/* + * This takes two audio buffers of the playing audio format and mixes + * them, performing addition, volume adjustment, and overflow clipping. + * The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume. Note this does not change hardware volume. + * This is provided for convenience -- you can mix your own audio data. + */ +#define SDL_MIX_MAXVOLUME 128 +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume); + +/* + * The lock manipulated by these functions protects the callback function. + * During a LockAudio/UnlockAudio pair, you can be guaranteed that the + * callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); + +/* + * This function shuts down audio processing and closes the audio device. + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_audio_h */ diff --git a/src/Menge/include/SDL/SDL_byteorder.h b/src/Menge/include/SDL/SDL_byteorder.h new file mode 100644 index 00000000..3871cfed --- /dev/null +++ b/src/Menge/include/SDL/SDL_byteorder.h @@ -0,0 +1,24 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* DEPRECATED */ +#include "SDL_endian.h" diff --git a/src/Menge/include/SDL/SDL_cdrom.h b/src/Menge/include/SDL/SDL_cdrom.h new file mode 100644 index 00000000..5f8f0c62 --- /dev/null +++ b/src/Menge/include/SDL/SDL_cdrom.h @@ -0,0 +1,171 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This is the CD-audio control API for Simple DirectMedia Layer */ + +#ifndef _SDL_cdrom_h +#define _SDL_cdrom_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* In order to use these functions, SDL_Init() must have been called + with the SDL_INIT_CDROM flag. This causes SDL to scan the system + for CD-ROM drives, and load appropriate drivers. +*/ + +/* The maximum number of CD-ROM tracks on a disk */ +#define SDL_MAX_TRACKS 99 + +/* The types of CD-ROM track possible */ +#define SDL_AUDIO_TRACK 0x00 +#define SDL_DATA_TRACK 0x04 + +/* The possible states which a CD-ROM drive can be in. */ +typedef enum { + CD_TRAYEMPTY, + CD_STOPPED, + CD_PLAYING, + CD_PAUSED, + CD_ERROR = -1 +} CDstatus; + +/* Given a status, returns true if there's a disk in the drive */ +#define CD_INDRIVE(status) ((int)(status) > 0) + +typedef struct SDL_CDtrack { + Uint8 id; /* Track number */ + Uint8 type; /* Data or audio track */ + Uint16 unused; + Uint32 length; /* Length, in frames, of this track */ + Uint32 offset; /* Offset, in frames, from start of disk */ +} SDL_CDtrack; + +/* This structure is only current as of the last call to SDL_CDStatus() */ +typedef struct SDL_CD { + int id; /* Private drive identifier */ + CDstatus status; /* Current drive status */ + + /* The rest of this structure is only valid if there's a CD in drive */ + int numtracks; /* Number of tracks on disk */ + int cur_track; /* Current track position */ + int cur_frame; /* Current frame offset within current track */ + SDL_CDtrack track[SDL_MAX_TRACKS+1]; +} SDL_CD; + +/* Conversion functions from frames to Minute/Second/Frames and vice versa */ +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + +/* CD-audio API functions: */ + +/* Returns the number of CD-ROM drives on the system, or -1 if + SDL_Init() has not been called with the SDL_INIT_CDROM flag. + */ +extern DECLSPEC int SDLCALL SDL_CDNumDrives(void); + +/* Returns a human-readable, system-dependent identifier for the CD-ROM. + Example: + "/dev/cdrom" + "E:" + "/dev/disk/ide/1/master" +*/ +extern DECLSPEC const char * SDLCALL SDL_CDName(int drive); + +/* Opens a CD-ROM drive for access. It returns a drive handle on success, + or NULL if the drive was invalid or busy. This newly opened CD-ROM + becomes the default CD used when other CD functions are passed a NULL + CD-ROM handle. + Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. +*/ +extern DECLSPEC SDL_CD * SDLCALL SDL_CDOpen(int drive); + +/* This function returns the current status of the given drive. + If the drive has a CD in it, the table of contents of the CD and current + play position of the CD will be stored in the SDL_CD structure. +*/ +extern DECLSPEC CDstatus SDLCALL SDL_CDStatus(SDL_CD *cdrom); + +/* Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' + tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play + until the end of the CD. This function will skip data tracks. + This function should only be called after calling SDL_CDStatus() to + get track information about the CD. + For example: + // Play entire CD: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); + // Play last track: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { + SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); + } + // Play first and second track and 10 seconds of third track: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); + + This function returns 0, or -1 if there was an error. +*/ +extern DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL_CD *cdrom, + int start_track, int start_frame, int ntracks, int nframes); + +/* Play the given CD starting at 'start' frame for 'length' frames. + It returns 0, or -1 if there was an error. +*/ +extern DECLSPEC int SDLCALL SDL_CDPlay(SDL_CD *cdrom, int start, int length); + +/* Pause play -- returns 0, or -1 on error */ +extern DECLSPEC int SDLCALL SDL_CDPause(SDL_CD *cdrom); + +/* Resume play -- returns 0, or -1 on error */ +extern DECLSPEC int SDLCALL SDL_CDResume(SDL_CD *cdrom); + +/* Stop play -- returns 0, or -1 on error */ +extern DECLSPEC int SDLCALL SDL_CDStop(SDL_CD *cdrom); + +/* Eject CD-ROM -- returns 0, or -1 on error */ +extern DECLSPEC int SDLCALL SDL_CDEject(SDL_CD *cdrom); + +/* Closes the handle for the CD-ROM drive */ +extern DECLSPEC void SDLCALL SDL_CDClose(SDL_CD *cdrom); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_video_h */ diff --git a/src/Menge/include/SDL/SDL_config.h b/src/Menge/include/SDL/SDL_config.h new file mode 100644 index 00000000..c82f42ad --- /dev/null +++ b/src/Menge/include/SDL/SDL_config.h @@ -0,0 +1,45 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_h +#define _SDL_config_h + +#include "SDL_platform.h" + +/* Add any platform that doesn't build using the configure system */ +#if defined(__DREAMCAST__) +#include "SDL_config_dreamcast.h" +#elif defined(__MACOS__) +#include "SDL_config_macos.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +#elif defined(__SYMBIAN32__) +#include "SDL_config_symbian.h" /* must be before win32! */ +#elif defined(__WIN32__) +#include "SDL_config_win32.h" +#elif defined(__OS2__) +#include "SDL_config_os2.h" +#else +#include "SDL_config_minimal.h" +#endif /* platform config */ + +#endif /* _SDL_config_h */ diff --git a/src/Menge/include/SDL/SDL_config_amiga.h b/src/Menge/include/SDL/SDL_config_amiga.h new file mode 100644 index 00000000..23e08619 --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_amiga.h @@ -0,0 +1,80 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_amiga_h +#define _SDL_config_amiga_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +#define SDL_HAS_64BIT_TYPE 1 + +/* Useful headers */ +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_AHI 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#define SDL_CDROM_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_AMIGA 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DUMMY 1 + +/* Enable various threading systems */ +#define SDL_THREAD_AMIGA 1 + +/* Enable various timer systems */ +#define SDL_TIMER_AMIGA 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_CYBERGRAPHICS 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 + +#endif /* _SDL_config_amiga_h */ diff --git a/src/Menge/include/SDL/SDL_config_dreamcast.h b/src/Menge/include/SDL/SDL_config_dreamcast.h new file mode 100644 index 00000000..9cbeea31 --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_dreamcast.h @@ -0,0 +1,106 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_dreamcast_h +#define _SDL_config_dreamcast_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +#define SDL_HAS_64BIT_TYPE 1 + +/* Useful headers */ +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRDUP 1 +#define HAVE_INDEX 1 +#define HAVE_RINDEX 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DC 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#define SDL_CDROM_DC 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DC 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DUMMY 1 + +/* Enable various threading systems */ +#define SDL_THREAD_DC 1 + +/* Enable various timer systems */ +#define SDL_TIMER_DC 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DC 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +#endif /* _SDL_config_dreamcast_h */ diff --git a/src/Menge/include/SDL/SDL_config_macos.h b/src/Menge/include/SDL/SDL_config_macos.h new file mode 100644 index 00000000..c4a1c598 --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_macos.h @@ -0,0 +1,112 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_macos_h +#define _SDL_config_macos_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +#include + +typedef SInt8 int8_t; +typedef UInt8 uint8_t; +typedef SInt16 int16_t; +typedef UInt16 uint16_t; +typedef SInt32 int32_t; +typedef UInt32 uint32_t; +typedef SInt64 int64_t; +typedef UInt64 uint64_t; +typedef unsigned long uintptr_t; + +#define SDL_HAS_64BIT_TYPE 1 + +/* Useful headers */ +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_SSCANF 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_SNDMGR 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#if TARGET_API_MAC_CARBON +#define SDL_CDROM_DUMMY 1 +#else +#define SDL_CDROM_MACOS 1 +#endif + +/* Enable various input drivers */ +#if TARGET_API_MAC_CARBON +#define SDL_JOYSTICK_DUMMY 1 +#else +#define SDL_JOYSTICK_MACOS 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_MACOS 1 + +/* Enable various threading systems */ +#define SDL_THREADS_DISABLED 1 + +/* Enable various timer systems */ +#define SDL_TIMER_MACOS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_DRAWSPROCKET 1 +#define SDL_VIDEO_DRIVER_TOOLBOX 1 + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 + +#endif /* _SDL_config_macos_h */ diff --git a/src/Menge/include/SDL/SDL_config_macosx.h b/src/Menge/include/SDL/SDL_config_macosx.h new file mode 100644 index 00000000..481c22ed --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_macosx.h @@ -0,0 +1,135 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_macosx_h +#define _SDL_config_macosx_h + +#include "SDL_platform.h" + +/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ +#include + +/* This is a set of defines to configure the SDL features */ + +#define SDL_HAS_64BIT_TYPE 1 + +/* Useful headers */ +/* If we specified an SDK or have a post-PowerPC chip, then alloca.h exists. */ +#if ( (MAC_OS_X_VERSION_MIN_REQUIRED >= 1030) || (!defined(__POWERPC__)) ) +#define HAVE_ALLOCA_H 1 +#endif +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +#define SDL_AUDIO_DRIVER_SNDMGR 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#define SDL_CDROM_MACOSX 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_IOKIT 1 + +/* Enable various shared object loading systems */ +#ifdef __ppc__ +/* For Mac OS X 10.2 compatibility */ +#define SDL_LOADSO_DLCOMPAT 1 +#else +#define SDL_LOADSO_DLOPEN 1 +#endif + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#if ((defined TARGET_API_MAC_CARBON) && (TARGET_API_MAC_CARBON)) +#define SDL_VIDEO_DRIVER_TOOLBOX 1 +#else +#define SDL_VIDEO_DRIVER_QUARTZ 1 +#endif + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 +#ifdef __ppc__ +#define SDL_ALTIVEC_BLITTERS 1 +#endif + +#endif /* _SDL_config_macosx_h */ diff --git a/src/Menge/include/SDL/SDL_config_minimal.h b/src/Menge/include/SDL/SDL_config_minimal.h new file mode 100644 index 00000000..62cf7ace --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_minimal.h @@ -0,0 +1,65 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_minimal_h +#define _SDL_config_minimal_h + +#include "SDL_platform.h" + +/* This is the minimal configuration that can be used to build SDL */ + +#include +#include + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +//typedef unsigned int size_t; + +// This line is removed by Horde3D team to make file Linux compatible +//typedef unsigned long uintptr_t; + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ +#define SDL_CDROM_DISABLED 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable the stub timer support (src/timer/dummy/\*.c) */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable the dummy video driver (src/video/dummy/\*.c) */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +#endif /* _SDL_config_minimal_h */ diff --git a/src/Menge/include/SDL/SDL_config_nds.h b/src/Menge/include/SDL/SDL_config_nds.h new file mode 100644 index 00000000..20b789c8 --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_nds.h @@ -0,0 +1,115 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_nds_h +#define _SDL_config_nds_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C datatypes */ +#define SDL_HAS_64BIT_TYPE 1 + +/* Endianness */ +#define SDL_BYTEORDER 1234 + +/* Useful headers */ +#define HAVE_ALLOCA_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_STRING_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_NDS 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ +#define SDL_CDROM_DISABLED 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_NDS 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable various timer systems */ +#define SDL_TIMER_NDS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_NDS 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +#endif /* _SDL_config_nds_h */ diff --git a/src/Menge/include/SDL/SDL_config_os2.h b/src/Menge/include/SDL/SDL_config_os2.h new file mode 100644 index 00000000..8cdea9ff --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_os2.h @@ -0,0 +1,141 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_os2_h +#define _SDL_config_os2_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef unsigned int size_t; +typedef unsigned long uintptr_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; + +#define SDL_HAS_64BIT_TYPE 1 + +/* Use Watcom's LIBC */ +#define HAVE_LIBC 1 + +/* Useful headers */ +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRDUP 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +#define HAVE_INDEX 1 +#define HAVE_RINDEX 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__UITOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE__I64TOA 1 +#define HAVE__UI64TOA 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 +#define HAVE_CLOCK_GETTIME 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DART 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#define SDL_CDROM_OS2 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_OS2 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_OS2 1 + +/* Enable various threading systems */ +#define SDL_THREAD_OS2 1 + +/* Enable various timer systems */ +#define SDL_TIMER_OS2 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_OS2FS 1 + +/* Enable OpenGL support */ +/* Nothing here yet for OS/2... :( */ + +/* Enable assembly routines where available */ +#define SDL_ASSEMBLY_ROUTINES 1 + +#endif /* _SDL_config_os2_h */ diff --git a/src/Menge/include/SDL/SDL_config_symbian.h b/src/Menge/include/SDL/SDL_config_symbian.h new file mode 100644 index 00000000..003a4915 --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_symbian.h @@ -0,0 +1,146 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* + +Symbian version Markus Mertama + +*/ + + +#ifndef _SDL_CONFIG_SYMBIAN_H +#define _SDL_CONFIG_SYMBIAN_H + +#include "SDL_platform.h" + +/* This is the minimal configuration that can be used to build SDL */ + + +#include +#include + + +#ifdef __GCCE__ +#define SYMBIAN32_GCCE +#endif + +#ifndef _SIZE_T_DEFINED +typedef unsigned int size_t; +#endif + +#ifndef _INTPTR_T_DECLARED +typedef unsigned int uintptr_t; +#endif + +#ifndef _INT8_T_DECLARED +typedef signed char int8_t; +#endif + +#ifndef _UINT8_T_DECLARED +typedef unsigned char uint8_t; +#endif + +#ifndef _INT16_T_DECLARED +typedef signed short int16_t; +#endif + +#ifndef _UINT16_T_DECLARED +typedef unsigned short uint16_t; +#endif + +#ifndef _INT32_T_DECLARED +typedef signed int int32_t; +#endif + +#ifndef _UINT32_T_DECLARED +typedef unsigned int uint32_t; +#endif + +#ifndef _INT64_T_DECLARED +typedef signed long long int64_t; +#endif + +#ifndef _UINT64_T_DECLARED +typedef unsigned long long uint64_t; +#endif + +#define SDL_AUDIO_DRIVER_EPOCAUDIO 1 + + +/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ +#define SDL_CDROM_DISABLED 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +#define SDL_THREAD_SYMBIAN 1 + +#define SDL_VIDEO_DRIVER_EPOC 1 + +#define SDL_VIDEO_OPENGL 0 + +#define SDL_HAS_64BIT_TYPE 1 + +#define HAVE_LIBC 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 + +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +//#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRUPR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +//#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_SSCANF 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + + + +#endif /* _SDL_CONFIG_SYMBIAN_H */ diff --git a/src/Menge/include/SDL/SDL_config_win32.h b/src/Menge/include/SDL/SDL_config_win32.h new file mode 100644 index 00000000..cfb44d2a --- /dev/null +++ b/src/Menge/include/SDL/SDL_config_win32.h @@ -0,0 +1,180 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_win32_h +#define _SDL_config_win32_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +#if defined(__GNUC__) || defined(__DMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#define SDL_HAS_64BIT_TYPE 1 + +/* Enabled for SDL 1.2 (binary compatibility) */ +#define HAVE_LIBC 1 +#ifdef HAVE_LIBC +/* Useful headers */ +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#ifndef _WIN32_WCE +#define HAVE_SIGNAL_H 1 +#endif + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_SSCANF 1 +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#ifndef _WIN32_WCE +#define SDL_AUDIO_DRIVER_DSOUND 1 +#endif +#define SDL_AUDIO_DRIVER_WAVEOUT 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various cdrom drivers */ +#ifdef _WIN32_WCE +#define SDL_CDROM_DISABLED 1 +#else +#define SDL_CDROM_WIN32 1 +#endif + +/* Enable various input drivers */ +#ifdef _WIN32_WCE +#define SDL_JOYSTICK_DISABLED 1 +#else +#define SDL_JOYSTICK_WINMM 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WIN32 1 + +/* Enable various threading systems */ +#define SDL_THREAD_WIN32 1 + +/* Enable various timer systems */ +#ifdef _WIN32_WCE +#define SDL_TIMER_WINCE 1 +#else +#define SDL_TIMER_WIN32 1 +#endif + +/* Enable various video drivers */ +#ifdef _WIN32_WCE +#define SDL_VIDEO_DRIVER_GAPI 1 +#endif +#ifndef _WIN32_WCE +#define SDL_VIDEO_DRIVER_DDRAW 1 +#endif +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDIB 1 + +/* Enable OpenGL support */ +#ifndef _WIN32_WCE +#define SDL_VIDEO_OPENGL 1 +#define SDL_VIDEO_OPENGL_WGL 1 +#endif + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* _SDL_config_win32_h */ diff --git a/src/Menge/include/SDL/SDL_copying.h b/src/Menge/include/SDL/SDL_copying.h new file mode 100644 index 00000000..39e122db --- /dev/null +++ b/src/Menge/include/SDL/SDL_copying.h @@ -0,0 +1,22 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + diff --git a/src/Menge/include/SDL/SDL_cpuinfo.h b/src/Menge/include/SDL/SDL_cpuinfo.h new file mode 100644 index 00000000..72acbdd8 --- /dev/null +++ b/src/Menge/include/SDL/SDL_cpuinfo.h @@ -0,0 +1,75 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* CPU feature detection for SDL */ + +#ifndef _SDL_cpuinfo_h +#define _SDL_cpuinfo_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This function returns true if the CPU has the RDTSC instruction + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/* This function returns true if the CPU has MMX features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/* This function returns true if the CPU has MMX Ext. features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMXExt(void); + +/* This function returns true if the CPU has 3DNow features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/* This function returns true if the CPU has 3DNow! Ext. features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNowExt(void); + +/* This function returns true if the CPU has SSE features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/* This function returns true if the CPU has SSE2 features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/* This function returns true if the CPU has AltiVec features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_cpuinfo_h */ diff --git a/src/Menge/include/SDL/SDL_endian.h b/src/Menge/include/SDL/SDL_endian.h new file mode 100644 index 00000000..8f8db4cc --- /dev/null +++ b/src/Menge/include/SDL/SDL_endian.h @@ -0,0 +1,194 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Functions for reading and writing endian-specific values */ + +#ifndef _SDL_endian_h +#define _SDL_endian_h + +#include "SDL_stdinc.h" + +/* The two types of endianness */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MISPEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* !SDL_BYTEORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Use inline functions for compilers that support them, and static + functions for those that do not. Because these functions become + static for compilers that do not support inline functions, this + header should only be included in files that actually use them. +*/ +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + Uint16 result; + + __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x)); + return result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint16 SDL_Swap16(Uint16 x) { + return((x<<8)|(x>>8)); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); + return result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint32 SDL_Swap32(Uint32 x) { + return((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24)); +} +#endif + +#ifdef SDL_HAS_64BIT_TYPE +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + union { + struct { Uint32 a,b; } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); + return v.u; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} +#else +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = (Uint32)(x&0xFFFFFFFF); + x >>= 32; + hi = (Uint32)(x&0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return(x); +} +#endif +#else +/* This is mainly to keep compilers from complaining in SDL code. + If there is no real 64-bit datatype, then compilers will complain about + the fake 64-bit datatype that SDL provides when it compiles user code. +*/ +#define SDL_Swap64(X) (X) +#endif /* SDL_HAS_64BIT_TYPE */ + + +/* Byteswap item from the specified endianness to the native endianness */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#endif + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_endian_h */ diff --git a/src/Menge/include/SDL/SDL_error.h b/src/Menge/include/SDL/SDL_error.h new file mode 100644 index 00000000..26d6bfae --- /dev/null +++ b/src/Menge/include/SDL/SDL_error.h @@ -0,0 +1,61 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Simple error message routines for SDL */ + +#ifndef _SDL_error_h +#define _SDL_error_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ +extern DECLSPEC void SDLCALL SDL_SetError(const char *fmt, ...); +extern DECLSPEC char * SDLCALL SDL_GetError(void); +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/* Private error message function - used internally */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +typedef enum { + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +extern DECLSPEC void SDLCALL SDL_Error(SDL_errorcode code); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_error_h */ diff --git a/src/Menge/include/SDL/SDL_events.h b/src/Menge/include/SDL/SDL_events.h new file mode 100644 index 00000000..9fe918c7 --- /dev/null +++ b/src/Menge/include/SDL/SDL_events.h @@ -0,0 +1,337 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL event handling */ + +#ifndef _SDL_events_h +#define _SDL_events_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_active.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_quit.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/* Event enumerations */ +typedef enum { + SDL_NOEVENT = 0, /* Unused (do not remove) */ + SDL_ACTIVEEVENT, /* Application loses/gains visibility */ + SDL_KEYDOWN, /* Keys pressed */ + SDL_KEYUP, /* Keys released */ + SDL_MOUSEMOTION, /* Mouse moved */ + SDL_MOUSEBUTTONDOWN, /* Mouse button pressed */ + SDL_MOUSEBUTTONUP, /* Mouse button released */ + SDL_JOYAXISMOTION, /* Joystick axis motion */ + SDL_JOYBALLMOTION, /* Joystick trackball motion */ + SDL_JOYHATMOTION, /* Joystick hat position change */ + SDL_JOYBUTTONDOWN, /* Joystick button pressed */ + SDL_JOYBUTTONUP, /* Joystick button released */ + SDL_QUIT, /* User-requested quit */ + SDL_SYSWMEVENT, /* System specific event */ + SDL_EVENT_RESERVEDA, /* Reserved for future use.. */ + SDL_EVENT_RESERVEDB, /* Reserved for future use.. */ + SDL_VIDEORESIZE, /* User resized video mode */ + SDL_VIDEOEXPOSE, /* Screen needs to be redrawn */ + SDL_EVENT_RESERVED2, /* Reserved for future use.. */ + SDL_EVENT_RESERVED3, /* Reserved for future use.. */ + SDL_EVENT_RESERVED4, /* Reserved for future use.. */ + SDL_EVENT_RESERVED5, /* Reserved for future use.. */ + SDL_EVENT_RESERVED6, /* Reserved for future use.. */ + SDL_EVENT_RESERVED7, /* Reserved for future use.. */ + /* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */ + SDL_USEREVENT = 24, + /* This last event is only for bounding internal arrays + It is the number of bits in the event mask datatype -- Uint32 + */ + SDL_NUMEVENTS = 32 +} SDL_EventType; + +/* Predefined event masks */ +#define SDL_EVENTMASK(X) (1<<(X)) +typedef enum { + SDL_ACTIVEEVENTMASK = SDL_EVENTMASK(SDL_ACTIVEEVENT), + SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), + SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), + SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN)| + SDL_EVENTMASK(SDL_KEYUP), + SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), + SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), + SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION)| + SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| + SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION), + SDL_JOYBALLMOTIONMASK = SDL_EVENTMASK(SDL_JOYBALLMOTION), + SDL_JOYHATMOTIONMASK = SDL_EVENTMASK(SDL_JOYHATMOTION), + SDL_JOYBUTTONDOWNMASK = SDL_EVENTMASK(SDL_JOYBUTTONDOWN), + SDL_JOYBUTTONUPMASK = SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_JOYEVENTMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION)| + SDL_EVENTMASK(SDL_JOYBALLMOTION)| + SDL_EVENTMASK(SDL_JOYHATMOTION)| + SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| + SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_VIDEORESIZEMASK = SDL_EVENTMASK(SDL_VIDEORESIZE), + SDL_VIDEOEXPOSEMASK = SDL_EVENTMASK(SDL_VIDEOEXPOSE), + SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT), + SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT) +} SDL_EventMask ; +#define SDL_ALLEVENTS 0xFFFFFFFF + +/* Application visibility event structure */ +typedef struct SDL_ActiveEvent { + Uint8 type; /* SDL_ACTIVEEVENT */ + Uint8 gain; /* Whether given states were gained or lost (1/0) */ + Uint8 state; /* A mask of the focus states */ +} SDL_ActiveEvent; + +/* Keyboard event structure */ +typedef struct SDL_KeyboardEvent { + Uint8 type; /* SDL_KEYDOWN or SDL_KEYUP */ + Uint8 which; /* The keyboard device index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ + SDL_keysym keysym; +} SDL_KeyboardEvent; + +/* Mouse motion event structure */ +typedef struct SDL_MouseMotionEvent { + Uint8 type; /* SDL_MOUSEMOTION */ + Uint8 which; /* The mouse device index */ + Uint8 state; /* The current button state */ + Uint16 x, y; /* The X/Y coordinates of the mouse */ + Sint16 xrel; /* The relative motion in the X direction */ + Sint16 yrel; /* The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/* Mouse button event structure */ +typedef struct SDL_MouseButtonEvent { + Uint8 type; /* SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP */ + Uint8 which; /* The mouse device index */ + Uint8 button; /* The mouse button index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ + Uint16 x, y; /* The X/Y coordinates of the mouse at press time */ +} SDL_MouseButtonEvent; + +/* Joystick axis motion event structure */ +typedef struct SDL_JoyAxisEvent { + Uint8 type; /* SDL_JOYAXISMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 axis; /* The joystick axis index */ + Sint16 value; /* The axis value (range: -32768 to 32767) */ +} SDL_JoyAxisEvent; + +/* Joystick trackball motion event structure */ +typedef struct SDL_JoyBallEvent { + Uint8 type; /* SDL_JOYBALLMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 ball; /* The joystick trackball index */ + Sint16 xrel; /* The relative motion in the X direction */ + Sint16 yrel; /* The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/* Joystick hat position change event structure */ +typedef struct SDL_JoyHatEvent { + Uint8 type; /* SDL_JOYHATMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 hat; /* The joystick hat index */ + Uint8 value; /* The hat position value: + SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP + SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT + SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN + Note that zero means the POV is centered. + */ +} SDL_JoyHatEvent; + +/* Joystick button event structure */ +typedef struct SDL_JoyButtonEvent { + Uint8 type; /* SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP */ + Uint8 which; /* The joystick device index */ + Uint8 button; /* The joystick button index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ +} SDL_JoyButtonEvent; + +/* The "window resized" event + When you get this event, you are responsible for setting a new video + mode with the new width and height. + */ +typedef struct SDL_ResizeEvent { + Uint8 type; /* SDL_VIDEORESIZE */ + int w; /* New width */ + int h; /* New height */ +} SDL_ResizeEvent; + +/* The "screen redraw" event */ +typedef struct SDL_ExposeEvent { + Uint8 type; /* SDL_VIDEOEXPOSE */ +} SDL_ExposeEvent; + +/* The "quit requested" event */ +typedef struct SDL_QuitEvent { + Uint8 type; /* SDL_QUIT */ +} SDL_QuitEvent; + +/* A user-defined event type */ +typedef struct SDL_UserEvent { + Uint8 type; /* SDL_USEREVENT through SDL_NUMEVENTS-1 */ + int code; /* User defined event code */ + void *data1; /* User defined data pointer */ + void *data2; /* User defined data pointer */ +} SDL_UserEvent; + +/* If you want to use this event, you should include SDL_syswm.h */ +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; +typedef struct SDL_SysWMEvent { + Uint8 type; + SDL_SysWMmsg *msg; +} SDL_SysWMEvent; + +/* General event structure */ +typedef union SDL_Event { + Uint8 type; + SDL_ActiveEvent active; + SDL_KeyboardEvent key; + SDL_MouseMotionEvent motion; + SDL_MouseButtonEvent button; + SDL_JoyAxisEvent jaxis; + SDL_JoyBallEvent jball; + SDL_JoyHatEvent jhat; + SDL_JoyButtonEvent jbutton; + SDL_ResizeEvent resize; + SDL_ExposeEvent expose; + SDL_QuitEvent quit; + SDL_UserEvent user; + SDL_SysWMEvent syswm; +} SDL_Event; + + +/* Function prototypes */ + +/* Pumps the event loop, gathering events from the input devices. + This function updates the event queue and internal input device state. + This should only be run in the thread that sets the video mode. +*/ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* Checks the event queue for messages and optionally returns them. + If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to + the back of the event queue. + If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front + of the event queue, matching 'mask', will be returned and will not + be removed from the queue. + If 'action' is SDL_GETEVENT, up to 'numevents' events at the front + of the event queue, matching 'mask', will be returned and will be + removed from the queue. + This function returns the number of events actually stored, or -1 + if there was an error. This function is thread-safe. +*/ +typedef enum { + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; +/* */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event *events, int numevents, + SDL_eventaction action, Uint32 mask); + +/* Polls for currently pending events, and returns 1 if there are any pending + events, or 0 if there are none available. If 'event' is not NULL, the next + event is removed from the queue and stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event *event); + +/* Waits indefinitely for the next available event, returning 1, or 0 if there + was an error while waiting for events. If 'event' is not NULL, the next + event is removed from the queue and stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event *event); + +/* Add an event to the event queue. + This function returns 0 on success, or -1 if the event queue was full + or there was some other error. + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event *event); + +/* + This function sets up a filter to process all events before they + change internal state and are posted to the internal event queue. + + The filter is protypted as: +*/ +typedef int (SDLCALL *SDL_EventFilter)(const SDL_Event *event); +/* + If the filter returns 1, then the event will be added to the internal queue. + If it returns 0, then the event will be dropped from the queue, but the + internal state will still be updated. This allows selective filtering of + dynamically arriving events. + + WARNING: Be very careful of what you do in the event filter function, as + it may run in a different thread! + + There is one caveat when dealing with the SDL_QUITEVENT event type. The + event filter is only called when the window manager desires to close the + application window. If the event filter returns 1, then the window will + be closed, otherwise the window will remain open if possible. + If the quit event is generated by an interrupt signal, it will bypass the + internal queue and be delivered to the application at the next event poll. +*/ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter); + +/* + Return the current event filter - can be used to "chain" filters. + If there is no event filter set, this function returns NULL. +*/ +extern DECLSPEC SDL_EventFilter SDLCALL SDL_GetEventFilter(void); + +/* + This function allows you to set the state of processing certain events. + If 'state' is set to SDL_IGNORE, that event will be automatically dropped + from the event queue and will not event be filtered. + If 'state' is set to SDL_ENABLE, that event will be processed normally. + If 'state' is set to SDL_QUERY, SDL_EventState() will return the + current processing state of the specified event. +*/ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint8 type, int state); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_events_h */ diff --git a/src/Menge/include/SDL/SDL_getenv.h b/src/Menge/include/SDL/SDL_getenv.h new file mode 100644 index 00000000..853b9ce4 --- /dev/null +++ b/src/Menge/include/SDL/SDL_getenv.h @@ -0,0 +1,24 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/src/Menge/include/SDL/SDL_image.h b/src/Menge/include/SDL/SDL_image.h new file mode 100644 index 00000000..a34ad026 --- /dev/null +++ b/src/Menge/include/SDL/SDL_image.h @@ -0,0 +1,138 @@ +/* + SDL_image: An example image loading library for use with SDL + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* A simple library to load images of various formats as SDL surfaces */ + +#ifndef _SDL_IMAGE_H +#define _SDL_IMAGE_H + +#include "SDL.h" +#include "SDL_version.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_IMAGE_MAJOR_VERSION 1 +#define SDL_IMAGE_MINOR_VERSION 2 +#define SDL_IMAGE_PATCHLEVEL 11 + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL_image library. + */ +#define SDL_IMAGE_VERSION(X) \ +{ \ + (X)->major = SDL_IMAGE_MAJOR_VERSION; \ + (X)->minor = SDL_IMAGE_MINOR_VERSION; \ + (X)->patch = SDL_IMAGE_PATCHLEVEL; \ +} + +/* This function gets the version of the dynamically linked SDL_image library. + it should NOT be used to fill a version structure, instead you should + use the SDL_IMAGE_VERSION() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL IMG_Linked_Version(void); + +typedef enum +{ + IMG_INIT_JPG = 0x00000001, + IMG_INIT_PNG = 0x00000002, + IMG_INIT_TIF = 0x00000004, + IMG_INIT_WEBP = 0x00000008 +} IMG_InitFlags; + +/* Loads dynamic libraries and prepares them for use. Flags should be + one or more flags from IMG_InitFlags OR'd together. + It returns the flags successfully initialized, or 0 on failure. + */ +extern DECLSPEC int SDLCALL IMG_Init(int flags); + +/* Unloads libraries loaded with IMG_Init */ +extern DECLSPEC void SDLCALL IMG_Quit(void); + +/* Load an image from an SDL data source. + The 'type' may be one of: "BMP", "GIF", "PNG", etc. + + If the image format supports a transparent pixel, SDL will set the + colorkey for the surface. You can enable RLE acceleration on the + surface afterwards by calling: + SDL_SetColorKey(image, SDL_RLEACCEL, image->format->colorkey); + */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, char *type); +/* Convenience functions */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_Load(const char *file); +extern DECLSPEC SDL_Surface * SDLCALL IMG_Load_RW(SDL_RWops *src, int freesrc); + +/* Invert the alpha of a surface for use with OpenGL + This function is now a no-op, and only provided for backwards compatibility. +*/ +extern DECLSPEC int SDLCALL IMG_InvertAlpha(int on); + +/* Functions to detect a file type, given a seekable source */ +extern DECLSPEC int SDLCALL IMG_isICO(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isCUR(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isBMP(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isGIF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isJPG(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isLBM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPCX(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPNG(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPNM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isTIF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXCF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXPM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXV(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isWEBP(SDL_RWops *src); + +/* Individual loading functions */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadICO_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadCUR_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadBMP_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadGIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadJPG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadLBM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPCX_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPNG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPNM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTGA_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXCF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXPM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXV_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadWEBP_RW(SDL_RWops *src); + +extern DECLSPEC SDL_Surface * SDLCALL IMG_ReadXPMFromArray(char **xpm); + +/* We'll use SDL for reporting errors */ +#define IMG_SetError SDL_SetError +#define IMG_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_IMAGE_H */ diff --git a/src/Menge/include/SDL/SDL_joystick.h b/src/Menge/include/SDL/SDL_joystick.h new file mode 100644 index 00000000..e4f72f1a --- /dev/null +++ b/src/Menge/include/SDL/SDL_joystick.h @@ -0,0 +1,167 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL joystick event handling */ + +#ifndef _SDL_joystick_h +#define _SDL_joystick_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* In order to use these functions, SDL_Init() must have been called + with the SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + for joysticks, and load appropriate drivers. +*/ + +/* The joystick structure used to identify an SDL joystick */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + + +/* Function prototypes */ +/* + * Count the number of joysticks attached to the system + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/* + * Get the implementation dependent name of a joystick. + * This can be called before any joysticks are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char * SDLCALL SDL_JoystickName(int device_index); + +/* + * Open a joystick for use - the index passed as an argument refers to + * the N'th joystick on the system. This index is the value which will + * identify this joystick in future joystick events. + * + * This function returns a joystick identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Joystick * SDLCALL SDL_JoystickOpen(int device_index); + +/* + * Returns 1 if the joystick has been opened, or 0 if it has not. + */ +extern DECLSPEC int SDLCALL SDL_JoystickOpened(int device_index); + +/* + * Get the device index of an opened joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickIndex(SDL_Joystick *joystick); + +/* + * Get the number of general axis controls on a joystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); + +/* + * Get the number of trackballs on a joystick + * Joystick trackballs have only relative motion events associated + * with them and their state cannot be polled. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); + +/* + * Get the number of POV hats on a joystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); + +/* + * Get the number of buttons on a joystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); + +/* + * Update the current state of the open joysticks. + * This is called automatically by the event loop if any joystick + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/* + * Enable/disable joystick event polling. + * If joystick events are disabled, you must call SDL_JoystickUpdate() + * yourself and check the state of the joystick when you want joystick + * information. + * The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +/* + * Get the current state of an axis control on a joystick + * The state is a value ranging from -32768 to 32767. + * The axis indices start at index 0. + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis); + +/* + * Get the current state of a POV hat on a joystick + * The return value is one of the following positions: + */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* + * The hat indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, int hat); + +/* + * Get the ball axis change since the last poll + * This returns 0, or -1 if you passed it invalid parameters. + * The ball indices start at index 0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy); + +/* + * Get the current state of a button on a joystick + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, int button); + +/* + * Close a joystick previously opened with SDL_JoystickOpen() + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_joystick_h */ diff --git a/src/Menge/include/SDL/SDL_keyboard.h b/src/Menge/include/SDL/SDL_keyboard.h new file mode 100644 index 00000000..1ad7dcaa --- /dev/null +++ b/src/Menge/include/SDL/SDL_keyboard.h @@ -0,0 +1,121 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL keyboard event handling */ + +#ifndef _SDL_keyboard_h +#define _SDL_keyboard_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keysym.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Keysym structure + - The scancode is hardware dependent, and should not be used by general + applications. If no hardware scancode is available, it will be 0. + + - The 'unicode' translated character is only available when character + translation is enabled by the SDL_EnableUNICODE() API. If non-zero, + this is a UNICODE character corresponding to the keypress. If the + high 9 bits of the character are 0, then this maps to the equivalent + ASCII character: + char ch; + if ( (keysym.unicode & 0xFF80) == 0 ) { + ch = keysym.unicode & 0x7F; + } else { + An international character.. + } + */ +typedef struct SDL_keysym { + Uint8 scancode; /* hardware specific scancode */ + SDLKey sym; /* SDL virtual keysym */ + SDLMod mod; /* current key modifiers */ + Uint16 unicode; /* translated character */ +} SDL_keysym; + +/* This is the mask which refers to all hotkey bindings */ +#define SDL_ALL_HOTKEYS 0xFFFFFFFF + +/* Function prototypes */ +/* + * Enable/Disable UNICODE translation of keyboard input. + * This translation has some overhead, so translation defaults off. + * If 'enable' is 1, translation is enabled. + * If 'enable' is 0, translation is disabled. + * If 'enable' is -1, the translation state is not changed. + * It returns the previous state of keyboard translation. + */ +extern DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable); + +/* + * Enable/Disable keyboard repeat. Keyboard repeat defaults to off. + * 'delay' is the initial delay in ms between the time when a key is + * pressed, and keyboard repeat begins. + * 'interval' is the time in ms between keyboard repeat events. + */ +#define SDL_DEFAULT_REPEAT_DELAY 500 +#define SDL_DEFAULT_REPEAT_INTERVAL 30 +/* + * If 'delay' is set to 0, keyboard repeat is disabled. + */ +extern DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval); +extern DECLSPEC void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval); + +/* + * Get a snapshot of the current state of the keyboard. + * Returns an array of keystates, indexed by the SDLK_* syms. + * Used: + * Uint8 *keystate = SDL_GetKeyState(NULL); + * if ( keystate[SDLK_RETURN] ) ... is pressed. + */ +extern DECLSPEC Uint8 * SDLCALL SDL_GetKeyState(int *numkeys); + +/* + * Get the current key modifier state + */ +extern DECLSPEC SDLMod SDLCALL SDL_GetModState(void); + +/* + * Set the current key modifier state + * This does not change the keyboard state, only the key modifier flags. + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDLMod modstate); + +/* + * Get the name of an SDL virtual keysym + */ +extern DECLSPEC char * SDLCALL SDL_GetKeyName(SDLKey key); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_keyboard_h */ diff --git a/src/Menge/include/SDL/SDL_keysym.h b/src/Menge/include/SDL/SDL_keysym.h new file mode 100644 index 00000000..ff44a035 --- /dev/null +++ b/src/Menge/include/SDL/SDL_keysym.h @@ -0,0 +1,311 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_keysym_h +#define _SDL_keysym_h + +/* What we really want is a mapping of every raw key on the keyboard. + To support international keyboards, we use the range 0xA1 - 0xFF + as international virtual keycodes. We'll follow in the footsteps of X11... + The names of the keys + */ + +typedef enum { + /* The keyboard syms have been cleverly chosen to map to ASCII */ + SDLK_UNKNOWN = 0, + SDLK_FIRST = 0, + SDLK_BACKSPACE = 8, + SDLK_TAB = 9, + SDLK_CLEAR = 12, + SDLK_RETURN = 13, + SDLK_PAUSE = 19, + SDLK_ESCAPE = 27, + SDLK_SPACE = 32, + SDLK_EXCLAIM = 33, + SDLK_QUOTEDBL = 34, + SDLK_HASH = 35, + SDLK_DOLLAR = 36, + SDLK_AMPERSAND = 38, + SDLK_QUOTE = 39, + SDLK_LEFTPAREN = 40, + SDLK_RIGHTPAREN = 41, + SDLK_ASTERISK = 42, + SDLK_PLUS = 43, + SDLK_COMMA = 44, + SDLK_MINUS = 45, + SDLK_PERIOD = 46, + SDLK_SLASH = 47, + SDLK_0 = 48, + SDLK_1 = 49, + SDLK_2 = 50, + SDLK_3 = 51, + SDLK_4 = 52, + SDLK_5 = 53, + SDLK_6 = 54, + SDLK_7 = 55, + SDLK_8 = 56, + SDLK_9 = 57, + SDLK_COLON = 58, + SDLK_SEMICOLON = 59, + SDLK_LESS = 60, + SDLK_EQUALS = 61, + SDLK_GREATER = 62, + SDLK_QUESTION = 63, + SDLK_AT = 64, + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = 91, + SDLK_BACKSLASH = 92, + SDLK_RIGHTBRACKET = 93, + SDLK_CARET = 94, + SDLK_UNDERSCORE = 95, + SDLK_BACKQUOTE = 96, + SDLK_a = 97, + SDLK_b = 98, + SDLK_c = 99, + SDLK_d = 100, + SDLK_e = 101, + SDLK_f = 102, + SDLK_g = 103, + SDLK_h = 104, + SDLK_i = 105, + SDLK_j = 106, + SDLK_k = 107, + SDLK_l = 108, + SDLK_m = 109, + SDLK_n = 110, + SDLK_o = 111, + SDLK_p = 112, + SDLK_q = 113, + SDLK_r = 114, + SDLK_s = 115, + SDLK_t = 116, + SDLK_u = 117, + SDLK_v = 118, + SDLK_w = 119, + SDLK_x = 120, + SDLK_y = 121, + SDLK_z = 122, + SDLK_DELETE = 127, + /* End of ASCII mapped keysyms */ + + /* International keyboard syms */ + SDLK_WORLD_0 = 160, /* 0xA0 */ + SDLK_WORLD_1 = 161, + SDLK_WORLD_2 = 162, + SDLK_WORLD_3 = 163, + SDLK_WORLD_4 = 164, + SDLK_WORLD_5 = 165, + SDLK_WORLD_6 = 166, + SDLK_WORLD_7 = 167, + SDLK_WORLD_8 = 168, + SDLK_WORLD_9 = 169, + SDLK_WORLD_10 = 170, + SDLK_WORLD_11 = 171, + SDLK_WORLD_12 = 172, + SDLK_WORLD_13 = 173, + SDLK_WORLD_14 = 174, + SDLK_WORLD_15 = 175, + SDLK_WORLD_16 = 176, + SDLK_WORLD_17 = 177, + SDLK_WORLD_18 = 178, + SDLK_WORLD_19 = 179, + SDLK_WORLD_20 = 180, + SDLK_WORLD_21 = 181, + SDLK_WORLD_22 = 182, + SDLK_WORLD_23 = 183, + SDLK_WORLD_24 = 184, + SDLK_WORLD_25 = 185, + SDLK_WORLD_26 = 186, + SDLK_WORLD_27 = 187, + SDLK_WORLD_28 = 188, + SDLK_WORLD_29 = 189, + SDLK_WORLD_30 = 190, + SDLK_WORLD_31 = 191, + SDLK_WORLD_32 = 192, + SDLK_WORLD_33 = 193, + SDLK_WORLD_34 = 194, + SDLK_WORLD_35 = 195, + SDLK_WORLD_36 = 196, + SDLK_WORLD_37 = 197, + SDLK_WORLD_38 = 198, + SDLK_WORLD_39 = 199, + SDLK_WORLD_40 = 200, + SDLK_WORLD_41 = 201, + SDLK_WORLD_42 = 202, + SDLK_WORLD_43 = 203, + SDLK_WORLD_44 = 204, + SDLK_WORLD_45 = 205, + SDLK_WORLD_46 = 206, + SDLK_WORLD_47 = 207, + SDLK_WORLD_48 = 208, + SDLK_WORLD_49 = 209, + SDLK_WORLD_50 = 210, + SDLK_WORLD_51 = 211, + SDLK_WORLD_52 = 212, + SDLK_WORLD_53 = 213, + SDLK_WORLD_54 = 214, + SDLK_WORLD_55 = 215, + SDLK_WORLD_56 = 216, + SDLK_WORLD_57 = 217, + SDLK_WORLD_58 = 218, + SDLK_WORLD_59 = 219, + SDLK_WORLD_60 = 220, + SDLK_WORLD_61 = 221, + SDLK_WORLD_62 = 222, + SDLK_WORLD_63 = 223, + SDLK_WORLD_64 = 224, + SDLK_WORLD_65 = 225, + SDLK_WORLD_66 = 226, + SDLK_WORLD_67 = 227, + SDLK_WORLD_68 = 228, + SDLK_WORLD_69 = 229, + SDLK_WORLD_70 = 230, + SDLK_WORLD_71 = 231, + SDLK_WORLD_72 = 232, + SDLK_WORLD_73 = 233, + SDLK_WORLD_74 = 234, + SDLK_WORLD_75 = 235, + SDLK_WORLD_76 = 236, + SDLK_WORLD_77 = 237, + SDLK_WORLD_78 = 238, + SDLK_WORLD_79 = 239, + SDLK_WORLD_80 = 240, + SDLK_WORLD_81 = 241, + SDLK_WORLD_82 = 242, + SDLK_WORLD_83 = 243, + SDLK_WORLD_84 = 244, + SDLK_WORLD_85 = 245, + SDLK_WORLD_86 = 246, + SDLK_WORLD_87 = 247, + SDLK_WORLD_88 = 248, + SDLK_WORLD_89 = 249, + SDLK_WORLD_90 = 250, + SDLK_WORLD_91 = 251, + SDLK_WORLD_92 = 252, + SDLK_WORLD_93 = 253, + SDLK_WORLD_94 = 254, + SDLK_WORLD_95 = 255, /* 0xFF */ + + /* Numeric keypad */ + SDLK_KP0 = 256, + SDLK_KP1 = 257, + SDLK_KP2 = 258, + SDLK_KP3 = 259, + SDLK_KP4 = 260, + SDLK_KP5 = 261, + SDLK_KP6 = 262, + SDLK_KP7 = 263, + SDLK_KP8 = 264, + SDLK_KP9 = 265, + SDLK_KP_PERIOD = 266, + SDLK_KP_DIVIDE = 267, + SDLK_KP_MULTIPLY = 268, + SDLK_KP_MINUS = 269, + SDLK_KP_PLUS = 270, + SDLK_KP_ENTER = 271, + SDLK_KP_EQUALS = 272, + + /* Arrows + Home/End pad */ + SDLK_UP = 273, + SDLK_DOWN = 274, + SDLK_RIGHT = 275, + SDLK_LEFT = 276, + SDLK_INSERT = 277, + SDLK_HOME = 278, + SDLK_END = 279, + SDLK_PAGEUP = 280, + SDLK_PAGEDOWN = 281, + + /* Function keys */ + SDLK_F1 = 282, + SDLK_F2 = 283, + SDLK_F3 = 284, + SDLK_F4 = 285, + SDLK_F5 = 286, + SDLK_F6 = 287, + SDLK_F7 = 288, + SDLK_F8 = 289, + SDLK_F9 = 290, + SDLK_F10 = 291, + SDLK_F11 = 292, + SDLK_F12 = 293, + SDLK_F13 = 294, + SDLK_F14 = 295, + SDLK_F15 = 296, + + /* Key state modifier keys */ + SDLK_NUMLOCK = 300, + SDLK_CAPSLOCK = 301, + SDLK_SCROLLOCK = 302, + SDLK_RSHIFT = 303, + SDLK_LSHIFT = 304, + SDLK_RCTRL = 305, + SDLK_LCTRL = 306, + SDLK_RALT = 307, + SDLK_LALT = 308, + SDLK_RMETA = 309, + SDLK_LMETA = 310, + SDLK_LSUPER = 311, /* Left "Windows" key */ + SDLK_RSUPER = 312, /* Right "Windows" key */ + SDLK_MODE = 313, /* "Alt Gr" key */ + SDLK_COMPOSE = 314, /* Multi-key compose key */ + + /* Miscellaneous function keys */ + SDLK_HELP = 315, + SDLK_PRINT = 316, + SDLK_SYSREQ = 317, + SDLK_BREAK = 318, + SDLK_MENU = 319, + SDLK_POWER = 320, /* Power Macintosh power key */ + SDLK_EURO = 321, /* Some european keyboards */ + SDLK_UNDO = 322, /* Atari keyboard has Undo */ + + /* Add any other keys here */ + + SDLK_LAST +} SDLKey; + +/* Enumeration of valid key mods (possibly OR'd together) */ +typedef enum { + KMOD_NONE = 0x0000, + KMOD_LSHIFT= 0x0001, + KMOD_RSHIFT= 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LMETA = 0x0400, + KMOD_RMETA = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000 +} SDLMod; + +#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) +#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) +#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define KMOD_META (KMOD_LMETA|KMOD_RMETA) + +#endif /* _SDL_keysym_h */ diff --git a/src/Menge/include/SDL/SDL_loadso.h b/src/Menge/include/SDL/SDL_loadso.h new file mode 100644 index 00000000..ce964494 --- /dev/null +++ b/src/Menge/include/SDL/SDL_loadso.h @@ -0,0 +1,74 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +/* Some things to keep in mind: + - These functions only work on C function names. Other languages may + have name mangling and intrinsic language support that varies from + compiler to compiler. + - Make sure you declare your function pointers with the same calling + convention as the actual library function. Your code will crash + mysteriously if you do not do this. + - Avoid namespace collisions. If you load a symbol from the library, + it is not defined whether or not it goes into the global symbol + namespace for the application. If it does and it conflicts with + symbols in your code or other shared libraries, you will not get + the results you expect. :) +*/ + + +#ifndef _SDL_loadso_h +#define _SDL_loadso_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This function dynamically loads a shared object and returns a pointer + * to the object handle (or NULL if there was an error). + * The 'sofile' parameter is a system dependent name of the object file. + */ +extern DECLSPEC void * SDLCALL SDL_LoadObject(const char *sofile); + +/* Given an object handle, this function looks up the address of the + * named function in the shared object and returns it. This address + * is no longer valid after calling SDL_UnloadObject(). + */ +extern DECLSPEC void * SDLCALL SDL_LoadFunction(void *handle, const char *name); + +/* Unload a shared object from memory */ +extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_loadso_h */ diff --git a/src/Menge/include/SDL/SDL_main.h b/src/Menge/include/SDL/SDL_main.h new file mode 100644 index 00000000..cf8b728d --- /dev/null +++ b/src/Menge/include/SDL/SDL_main.h @@ -0,0 +1,98 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_main_h +#define _SDL_main_h + +#include "SDL_stdinc.h" + +/* Redefine main() on Win32 and MacOS so that it is called by winmain.c */ + +#if defined(__WIN32__) || \ + (defined(__MWERKS__) && !defined(__BEOS__)) || \ + defined(__MACOS__) || defined(__MACOSX__) || \ + defined(__SYMBIAN32__) || defined(QWS) + +#ifdef __cplusplus +#define C_LINKAGE "C" +#else +#define C_LINKAGE +#endif /* __cplusplus */ + +/* The application's main() function must be called with C linkage, + and should be declared like this: +#ifdef __cplusplus +extern "C" +#endif + int main(int argc, char *argv[]) + { + } + */ +#define main SDL_main + +/* The prototype for the application's main() function */ +extern C_LINKAGE int SDL_main(int argc, char *argv[]); + + +/* From the SDL library code -- needed for registering the app on Win32 */ +#ifdef __WIN32__ + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be called from your WinMain() function, if any */ +extern DECLSPEC void SDLCALL SDL_SetModuleHandle(void *hInst); +/* This can also be called, but is no longer necessary */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(char *name, Uint32 style, void *hInst); +/* This can also be called, but is no longer necessary (SDL_Quit calls it) */ +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +/* From the SDL library code -- needed for registering QuickDraw on MacOS */ +#if defined(__MACOS__) + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declaration so we don't need to include QuickDraw.h */ +struct QDGlobals; + +/* This should be called from your main() function, if any */ +extern DECLSPEC void SDLCALL SDL_InitQuickDraw(struct QDGlobals *the_qd); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +#endif /* Need to redefine main()? */ + +#endif /* _SDL_main_h */ diff --git a/src/Menge/include/SDL/SDL_mouse.h b/src/Menge/include/SDL/SDL_mouse.h new file mode 100644 index 00000000..c2364d85 --- /dev/null +++ b/src/Menge/include/SDL/SDL_mouse.h @@ -0,0 +1,136 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL mouse event handling */ + +#ifndef _SDL_mouse_h +#define _SDL_mouse_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WMcursor WMcursor; /* Implementation dependent */ +typedef struct SDL_Cursor { + SDL_Rect area; /* The area of the mouse cursor */ + Sint16 hot_x, hot_y; /* The "tip" of the cursor */ + Uint8 *data; /* B/W cursor data */ + Uint8 *mask; /* B/W cursor mask */ + Uint8 *save[2]; /* Place to save cursor area */ + WMcursor *wm_cursor; /* Window-manager cursor */ +} SDL_Cursor; + +/* Function prototypes */ +/* + * Retrieve the current state of the mouse. + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * current mouse cursor position. You can pass NULL for either x or y. + */ +extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y); + +/* + * Retrieve the current state of the mouse. + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState(). + */ +extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/* + * Set the position of the mouse cursor (generates a mouse motion event) + */ +extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y); + +/* + * Create a cursor using the specified data and mask (in MSB format). + * The cursor width must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * data mask resulting pixel on screen + * 0 1 White + * 1 1 Black + * 0 0 Transparent + * 1 0 Inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_FreeCursor(). + */ +extern DECLSPEC SDL_Cursor * SDLCALL SDL_CreateCursor + (Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + +/* + * Set the currently active cursor to the specified one. + * If the cursor is currently visible, the change will be immediately + * represented on the display. + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor *cursor); + +/* + * Returns the currently active cursor. + */ +extern DECLSPEC SDL_Cursor * SDLCALL SDL_GetCursor(void); + +/* + * Deallocates a cursor created with SDL_CreateCursor(). + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor *cursor); + +/* + * Toggle whether or not the cursor is shown on the screen. + * The cursor start off displayed, but can be turned off. + * SDL_ShowCursor() returns 1 if the cursor was being displayed + * before the call, or 0 if it was not. You can query the current + * state by passing a 'toggle' value of -1. + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/* Used as a mask when testing buttons in buttonstate + Button 1: Left mouse button + Button 2: Middle mouse button + Button 3: Right mouse button + Button 4: Mouse wheel up (may also be a real button) + Button 5: Mouse wheel down (may also be a real button) + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_WHEELUP 4 +#define SDL_BUTTON_WHEELDOWN 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mouse_h */ diff --git a/src/Menge/include/SDL/SDL_mutex.h b/src/Menge/include/SDL/SDL_mutex.h new file mode 100644 index 00000000..00165281 --- /dev/null +++ b/src/Menge/include/SDL/SDL_mutex.h @@ -0,0 +1,162 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_mutex_h +#define _SDL_mutex_h + +/* Functions to provide thread synchronization primitives + + These are independent of the other SDL routines. +*/ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Synchronization functions which can time out return this value + if they time out. +*/ +#define SDL_MUTEX_TIMEDOUT 1 + +/* This is the timeout value which corresponds to never time out */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Mutex functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL mutex structure, defined in SDL_mutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/* Create a mutex, initialized unlocked */ +extern DECLSPEC SDL_mutex * SDLCALL SDL_CreateMutex(void); + +/* Lock the mutex (Returns 0, or -1 on error) */ +#define SDL_LockMutex(m) SDL_mutexP(m) +extern DECLSPEC int SDLCALL SDL_mutexP(SDL_mutex *mutex); + +/* Unlock the mutex (Returns 0, or -1 on error) + It is an error to unlock a mutex that has not been locked by + the current thread, and doing so results in undefined behavior. + */ +#define SDL_UnlockMutex(m) SDL_mutexV(m) +extern DECLSPEC int SDLCALL SDL_mutexV(SDL_mutex *mutex); + +/* Destroy a mutex */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Semaphore functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL semaphore structure, defined in SDL_sem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/* Create a semaphore, initialized with value, returns NULL on failure. */ +extern DECLSPEC SDL_sem * SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/* Destroy a semaphore */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem); + +/* This function suspends the calling thread until the semaphore pointed + * to by sem has a positive count. It then atomically decreases the semaphore + * count. + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem); + +/* Non-blocking variant of SDL_SemWait(), returns 0 if the wait succeeds, + SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error. +*/ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem); + +/* Variant of SDL_SemWait() with a timeout in milliseconds, returns 0 if + the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in + the allotted time, and -1 on error. + On some platforms this function is implemented by looping with a delay + of 1 ms, and so should be avoided if possible. +*/ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 ms); + +/* Atomically increases the semaphore's count (not blocking), returns 0, + or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem); + +/* Returns the current count of the semaphore */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Condition variable functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL condition variable structure, defined in SDL_cond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/* Create a condition variable */ +extern DECLSPEC SDL_cond * SDLCALL SDL_CreateCond(void); + +/* Destroy a condition variable */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond *cond); + +/* Restart one of the threads that are waiting on the condition variable, + returns 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond *cond); + +/* Restart all threads that are waiting on the condition variable, + returns 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond *cond); + +/* Wait on the condition variable, unlocking the provided mutex. + The mutex must be locked before entering this function! + The mutex is re-locked once the condition variable is signaled. + Returns 0 when it is signaled, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond *cond, SDL_mutex *mut); + +/* Waits for at most 'ms' milliseconds, and returns 0 if the condition + variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not + signaled in the allotted time, and -1 on error. + On some platforms this function is implemented by looping with a delay + of 1 ms, and so should be avoided if possible. +*/ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mutex_h */ diff --git a/src/Menge/include/SDL/SDL_name.h b/src/Menge/include/SDL/SDL_name.h new file mode 100644 index 00000000..511619af --- /dev/null +++ b/src/Menge/include/SDL/SDL_name.h @@ -0,0 +1,11 @@ + +#ifndef _SDLname_h_ +#define _SDLname_h_ + +#if defined(__STDC__) || defined(__cplusplus) +#define NeedFunctionPrototypes 1 +#endif + +#define SDL_NAME(X) SDL_##X + +#endif /* _SDLname_h_ */ diff --git a/src/Menge/include/SDL/SDL_opengl.h b/src/Menge/include/SDL/SDL_opengl.h new file mode 100644 index 00000000..36c0a309 --- /dev/null +++ b/src/Menge/include/SDL/SDL_opengl.h @@ -0,0 +1,6551 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This is a simple file to encapsulate the OpenGL API headers */ + +#include "SDL_config.h" + +#ifdef __WIN32__ +#define WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX /* Don't defined min() and max() */ +#endif +#include +#endif +#ifndef NO_SDL_GLEXT +#define __glext_h_ /* Don't let gl.h include glext.h */ +#endif +#if defined(__MACOSX__) +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ +#elif defined(__MACOS__) +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ +#else +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ +#endif +#ifndef NO_SDL_GLEXT +#undef __glext_h_ +#endif + +/* This file taken from "GLext.h" from the Jeff Molofee OpenGL tutorials. + It is included here because glext.h is not available on some systems. + If you don't want this version included, simply define "NO_SDL_GLEXT" + */ +#ifndef NO_SDL_GLEXT +#if !defined(__glext_h_) && !defined(GL_GLEXT_LEGACY) +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glext.h last updated 2005/06/20 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define GL_GLEXT_VERSION 29 + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#endif + +#ifndef GL_VERSION_2_0 +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_env_add +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_window_pos +#endif + +#ifndef GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + +#ifndef GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_compression_vtc +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_NV_vertex_program1_1 +#endif + +#ifndef GL_EXT_shadow_funcs +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_NV_vertex_program2 +#endif + +#ifndef GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + +#ifndef GL_NV_fragment_program_option +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + +#ifndef GL_NV_vertex_program2_option +/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ +/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ +#endif + +#ifndef GL_NV_vertex_program3 +/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#endif + +#ifndef GL_GREMEDY_string_marker +#endif + + +/*************************************************************/ + +#include +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; /* native character */ +#endif + +#ifndef GL_VERSION_1_5 +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for handling shader object handles and program/shader text */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ +#endif + +/* GL types for "half" precision (s10e5) float data in host memory */ +#ifndef GL_ARB_half_float_pixel +typedef unsigned short GLhalfARB; +#endif + +#ifndef GL_NV_half_float +typedef unsigned short GLhalfNV; +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +GLAPI void APIENTRY glBlendEquation (GLenum); +GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogram (GLenum); +GLAPI void APIENTRY glResetMinmax (GLenum); +GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum); +GLAPI void APIENTRY glClientActiveTexture (GLenum); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glFogCoordf (GLfloat); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *); +GLAPI void APIENTRY glFogCoordd (GLdouble); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); +GLAPI void APIENTRY glPointParameteri (GLenum, GLint); +GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); +GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos2i (GLint, GLint); +GLAPI void APIENTRY glWindowPos2iv (const GLint *); +GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *); +GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3iv (const GLint *); +GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsQuery (GLuint); +GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); +GLAPI void APIENTRY glEndQuery (GLenum); +GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); +GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); +GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint); +GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); +GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); +GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); +GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum); +GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *); +GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint); +GLAPI void APIENTRY glAttachShader (GLuint, GLuint); +GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); +GLAPI void APIENTRY glCompileShader (GLuint); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum); +GLAPI void APIENTRY glDeleteProgram (GLuint); +GLAPI void APIENTRY glDeleteShader (GLuint); +GLAPI void APIENTRY glDetachShader (GLuint, GLuint); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint); +GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); +GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); +GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); +GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgram (GLuint); +GLAPI GLboolean APIENTRY glIsShader (GLuint); +GLAPI void APIENTRY glLinkProgram (GLuint); +GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); +GLAPI void APIENTRY glUseProgram (GLuint); +GLAPI void APIENTRY glUniform1f (GLint, GLfloat); +GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform1i (GLint, GLint); +GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint); +GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glValidateProgram (GLuint); +GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); +GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); +GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); +GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); +GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); +GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexBlendARB (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); +GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); +GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); +GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); +GLAPI void APIENTRY glEndQueryARB (GLenum); +GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); +GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); +GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); +GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); +GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); +GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); +GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); +GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); +GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); +GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); +GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); +GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); +GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform1iARB (GLint, GLint); +GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); +GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); +GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); +GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); +GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); +GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); +GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); +GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); +GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClampColorARB (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +#endif + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogramEXT (GLenum); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint); +GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +GLAPI void APIENTRY glDeformSGIX (GLbitfield); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum); +GLAPI void APIENTRY glTextureLightEXT (GLenum); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); +GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); +GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); +GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *); +GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); +GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); +GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); +GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); +GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFinishFenceNV (GLuint); +GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); +GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); +GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); +GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); +GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); +GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); +GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); +GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); +GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); +GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); +GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); +GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); +GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#endif + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +/* This is really a WGL extension, but defines some associated GL enums. + * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. + */ +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#endif + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#endif + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#endif + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint); +GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); +GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); +GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); +GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint); +GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); +GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); +GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGenerateMipmapEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#endif + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif +#endif /* NO_SDL_GLEXT */ diff --git a/src/Menge/include/SDL/SDL_platform.h b/src/Menge/include/SDL/SDL_platform.h new file mode 100644 index 00000000..1bfee29e --- /dev/null +++ b/src/Menge/include/SDL/SDL_platform.h @@ -0,0 +1,100 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Try to get a standard set of platform defines */ + +#ifndef _SDL_platform_h +#define _SDL_platform_h + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__BEOS__) +#undef __BEOS__ +#define __BEOS__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if defined(linux) || defined(__linux) || defined(__linux__) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(__APPLE__) +#undef __MACOSX__ +#define __MACOSX__ 1 +#elif defined(macintosh) +#undef __MACOS__ +#define __MACOS__ 1 +#endif +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif +#if defined(WIN32) || defined(_WIN32) +#undef __WIN32__ +#define __WIN32__ 1 +#endif + +#endif /* _SDL_platform_h */ diff --git a/src/Menge/include/SDL/SDL_quit.h b/src/Menge/include/SDL/SDL_quit.h new file mode 100644 index 00000000..fcf40fbd --- /dev/null +++ b/src/Menge/include/SDL/SDL_quit.h @@ -0,0 +1,50 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL quit event handling */ + +#ifndef _SDL_quit_h +#define _SDL_quit_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* + An SDL_QUITEVENT is generated when the user tries to close the application + window. If it is ignored or filtered out, the window will remain open. + If it is not ignored or filtered, it is queued normally and the window + is allowed to close. When the window is closed, screen updates will + complete, but have no effect. + + SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) + and SIGTERM (system termination request), if handlers do not already + exist, that generate SDL_QUITEVENT events as well. There is no way + to determine the cause of an SDL_QUITEVENT, but setting a signal + handler in your application will override the default generation of + quit events for that signal. +*/ + +/* There are no functions directly affecting the quit event */ +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUITMASK)) + +#endif /* _SDL_quit_h */ diff --git a/src/Menge/include/SDL/SDL_rwops.h b/src/Menge/include/SDL/SDL_rwops.h new file mode 100644 index 00000000..8c177017 --- /dev/null +++ b/src/Menge/include/SDL/SDL_rwops.h @@ -0,0 +1,144 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This file provides a general interface for SDL to read and write + data sources. It can easily be extended to files, memory, etc. +*/ + +#ifndef _SDL_rwops_h +#define _SDL_rwops_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the read/write operation structure -- very basic */ + +typedef struct SDL_RWops { + /* Seek to 'offset' relative to whence, one of stdio's whence values: + SEEK_SET, SEEK_CUR, SEEK_END + Returns the final offset in the data source. + */ + int (SDLCALL *seek)(struct SDL_RWops *context, int offset, int whence); + + /* Read up to 'num' objects each of size 'objsize' from the data + source to the area pointed at by 'ptr'. + Returns the number of objects read, or -1 if the read failed. + */ + int (SDLCALL *read)(struct SDL_RWops *context, void *ptr, int size, int maxnum); + + /* Write exactly 'num' objects each of size 'objsize' from the area + pointed at by 'ptr' to data source. + Returns 'num', or -1 if the write failed. + */ + int (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, int size, int num); + + /* Close and free an allocated SDL_FSops structure */ + int (SDLCALL *close)(struct SDL_RWops *context); + + Uint32 type; + union { +#if defined(__WIN32__) && !defined(__SYMBIAN32__) + struct { + int append; + void *h; + struct { + void *data; + int size; + int left; + } buffer; + } win32io; +#endif +#ifdef HAVE_STDIO_H + struct { + int autoclose; + FILE *fp; + } stdio; +#endif + struct { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct { + void *data1; + } unknown; + } hidden; + +} SDL_RWops; + + +/* Functions to create SDL_RWops structures from various data sources */ + +extern DECLSPEC SDL_RWops * SDLCALL SDL_RWFromFile(const char *file, const char *mode); + +#ifdef HAVE_STDIO_H +extern DECLSPEC SDL_RWops * SDLCALL SDL_RWFromFP(FILE *fp, int autoclose); +#endif + +extern DECLSPEC SDL_RWops * SDLCALL SDL_RWFromMem(void *mem, int size); +extern DECLSPEC SDL_RWops * SDLCALL SDL_RWFromConstMem(const void *mem, int size); + +extern DECLSPEC SDL_RWops * SDLCALL SDL_AllocRW(void); +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops *area); + +#define RW_SEEK_SET 0 /* Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /* Seek relative to current read point */ +#define RW_SEEK_END 2 /* Seek relative to the end of data */ + +/* Macros to easily read and write from an SDL_RWops structure */ +#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) +#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR) +#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) +#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n) +#define SDL_RWclose(ctx) (ctx)->close(ctx) + + +/* Read an item of the specified endianness and return in native format */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops *src); +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops *src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops *src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops *src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops *src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops *src); + +/* Write an item of native format to the specified endianness */ +extern DECLSPEC int SDLCALL SDL_WriteLE16(SDL_RWops *dst, Uint16 value); +extern DECLSPEC int SDLCALL SDL_WriteBE16(SDL_RWops *dst, Uint16 value); +extern DECLSPEC int SDLCALL SDL_WriteLE32(SDL_RWops *dst, Uint32 value); +extern DECLSPEC int SDLCALL SDL_WriteBE32(SDL_RWops *dst, Uint32 value); +extern DECLSPEC int SDLCALL SDL_WriteLE64(SDL_RWops *dst, Uint64 value); +extern DECLSPEC int SDLCALL SDL_WriteBE64(SDL_RWops *dst, Uint64 value); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_rwops_h */ diff --git a/src/Menge/include/SDL/SDL_stdinc.h b/src/Menge/include/SDL/SDL_stdinc.h new file mode 100644 index 00000000..891a9ac8 --- /dev/null +++ b/src/Menge/include/SDL/SDL_stdinc.h @@ -0,0 +1,594 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This is a general header that includes C language support */ + +#ifndef _SDL_stdinc_h +#define _SDL_stdinc_h + +#include "SDL_config.h" + + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_ICONV_H +# include +#endif + +/* The number of elements in an array */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/* Basic data types */ +typedef enum SDL_bool { + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; + +typedef int8_t Sint8; +typedef uint8_t Uint8; +typedef int16_t Sint16; +typedef uint16_t Uint16; +typedef int32_t Sint32; +typedef uint32_t Uint32; + +#ifdef SDL_HAS_64BIT_TYPE +typedef int64_t Sint64; +#ifndef SYMBIAN32_GCCE +typedef uint64_t Uint64; +#endif +#else +/* This is really just a hack to prevent the compiler from complaining */ +typedef struct { + Uint32 hi; + Uint32 lo; +} Uint64, Sint64; +#endif + +/* Make sure the types really have the right sizes */ +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_dummy_ ## name[(x) * 2 - 1] + +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ +/* Enable enums always int in CodeWarrior (for MPW use "-enum int") */ +#ifdef __MWERKS__ +#pragma enumsalwaysint on +#endif + +typedef enum { + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +#ifndef __NDS__ +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_MALLOC +#define SDL_malloc malloc +#else +extern DECLSPEC void * SDLCALL SDL_malloc(size_t size); +#endif + +#ifdef HAVE_CALLOC +#define SDL_calloc calloc +#else +extern DECLSPEC void * SDLCALL SDL_calloc(size_t nmemb, size_t size); +#endif + +#ifdef HAVE_REALLOC +#define SDL_realloc realloc +#else +extern DECLSPEC void * SDLCALL SDL_realloc(void *mem, size_t size); +#endif + +#ifdef HAVE_FREE +#define SDL_free free +#else +extern DECLSPEC void SDLCALL SDL_free(void *mem); +#endif + +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) + #pragma alloca +# elif defined(__MRC__) + void *alloca (unsigned); +# else + char *alloca (); +# endif +#endif +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +#ifdef HAVE_GETENV +#define SDL_getenv getenv +#else +extern DECLSPEC char * SDLCALL SDL_getenv(const char *name); +#endif + +#ifdef HAVE_PUTENV +#define SDL_putenv putenv +#else +extern DECLSPEC int SDLCALL SDL_putenv(const char *variable); +#endif + +#ifdef HAVE_QSORT +#define SDL_qsort qsort +#else +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, + int (*compare)(const void *, const void *)); +#endif + +#ifdef HAVE_ABS +#define SDL_abs abs +#else +#define SDL_abs(X) ((X) < 0 ? -(X) : (X)) +#endif + +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef HAVE_CTYPE_H +#define SDL_isdigit(X) isdigit(X) +#define SDL_isspace(X) isspace(X) +#define SDL_toupper(X) toupper(X) +#define SDL_tolower(X) tolower(X) +#else +#define SDL_isdigit(X) (((X) >= '0') && ((X) <= '9')) +#define SDL_isspace(X) (((X) == ' ') || ((X) == '\t') || ((X) == '\r') || ((X) == '\n')) +#define SDL_toupper(X) (((X) >= 'a') && ((X) <= 'z') ? ('A'+((X)-'a')) : (X)) +#define SDL_tolower(X) (((X) >= 'A') && ((X) <= 'Z') ? ('a'+((X)-'A')) : (X)) +#endif + +#ifdef HAVE_MEMSET +#define SDL_memset memset +#else +extern DECLSPEC void * SDLCALL SDL_memset(void *dst, int c, size_t len); +#endif + +#if defined(__GNUC__) && defined(i386) +#define SDL_memset4(dst, val, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; stosl\n\t" \ + : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ + : "0" (dst), "1" (val), "2" ((Uint32)(len)) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memset4 +#define SDL_memset4(dst, val, len) \ +do { \ + unsigned _count = (len); \ + unsigned _n = (_count + 3) / 4; \ + Uint32 *_p = (Uint32 *)(dst); \ + Uint32 _val = (val); \ + switch (_count % 4) { \ + case 0: do { *_p++ = _val; \ + case 3: *_p++ = _val; \ + case 2: *_p++ = _val; \ + case 1: *_p++ = _val; \ + } while ( --_n ); \ + } \ +} while(0) +#endif + +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) +#elif defined(__GNUC__) && defined(i386) +#define SDL_memcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl\n\t" \ + "testb $2,%b4\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b4\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" ((unsigned)(len)/4), "q" (len), "1" (dst),"2" (src) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memcpy +#ifdef HAVE_MEMCPY +#define SDL_memcpy memcpy +#elif defined(HAVE_BCOPY) +#define SDL_memcpy(d, s, n) bcopy((s), (d), (n)) +#else +extern DECLSPEC void * SDLCALL SDL_memcpy(void *dst, const void *src, size_t len); +#endif +#endif + +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len)*4) +#elif defined(__GNUC__) && defined(i386) +#define SDL_memcpy4(dst, src, len) \ +do { \ + int ecx, edi, esi; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl" \ + : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ + : "0" ((unsigned)(len)), "1" (dst), "2" (src) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memcpy4 +#define SDL_memcpy4(dst, src, len) SDL_memcpy(dst, src, (len) << 2) +#endif + +#if defined(__GNUC__) && defined(i386) +#define SDL_revcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + char *dstp = (char *)(dst); \ + char *srcp = (char *)(src); \ + int n = (len); \ + if ( n >= 4 ) { \ + __asm__ __volatile__ ( \ + "std\n\t" \ + "rep ; movsl\n\t" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (n >> 2), \ + "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ + : "memory" ); \ + } \ + switch (n & 3) { \ + case 3: dstp[2] = srcp[2]; \ + case 2: dstp[1] = srcp[1]; \ + case 1: dstp[0] = srcp[0]; \ + break; \ + default: \ + break; \ + } \ +} while(0) +#endif +#ifndef SDL_revcpy +extern DECLSPEC void * SDLCALL SDL_revcpy(void *dst, const void *src, size_t len); +#endif + +#ifdef HAVE_MEMMOVE +#define SDL_memmove memmove +#elif defined(HAVE_BCOPY) +#define SDL_memmove(d, s, n) bcopy((s), (d), (n)) +#else +#define SDL_memmove(dst, src, len) \ +do { \ + if ( dst < src ) { \ + SDL_memcpy(dst, src, len); \ + } else { \ + SDL_revcpy(dst, src, len); \ + } \ +} while(0) +#endif + +#ifdef HAVE_MEMCMP +#define SDL_memcmp memcmp +#else +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); +#endif + +#ifdef HAVE_STRLEN +#define SDL_strlen strlen +#else +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *string); +#endif + +#ifdef HAVE_STRLCPY +#define SDL_strlcpy strlcpy +#else +extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen); +#endif + +#ifdef HAVE_STRLCAT +#define SDL_strlcat strlcat +#else +extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, size_t maxlen); +#endif + +#ifdef HAVE_STRDUP +#define SDL_strdup strdup +#else +extern DECLSPEC char * SDLCALL SDL_strdup(const char *string); +#endif + +#ifdef HAVE__STRREV +#define SDL_strrev _strrev +#else +extern DECLSPEC char * SDLCALL SDL_strrev(char *string); +#endif + +#ifdef HAVE__STRUPR +#define SDL_strupr _strupr +#else +extern DECLSPEC char * SDLCALL SDL_strupr(char *string); +#endif + +#ifdef HAVE__STRLWR +#define SDL_strlwr _strlwr +#else +extern DECLSPEC char * SDLCALL SDL_strlwr(char *string); +#endif + +#ifdef HAVE_STRCHR +#define SDL_strchr strchr +#elif defined(HAVE_INDEX) +#define SDL_strchr index +#else +extern DECLSPEC char * SDLCALL SDL_strchr(const char *string, int c); +#endif + +#ifdef HAVE_STRRCHR +#define SDL_strrchr strrchr +#elif defined(HAVE_RINDEX) +#define SDL_strrchr rindex +#else +extern DECLSPEC char * SDLCALL SDL_strrchr(const char *string, int c); +#endif + +#ifdef HAVE_STRSTR +#define SDL_strstr strstr +#else +extern DECLSPEC char * SDLCALL SDL_strstr(const char *haystack, const char *needle); +#endif + +#ifdef HAVE_ITOA +#define SDL_itoa itoa +#else +#define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) +#endif + +#ifdef HAVE__LTOA +#define SDL_ltoa _ltoa +#else +extern DECLSPEC char * SDLCALL SDL_ltoa(long value, char *string, int radix); +#endif + +#ifdef HAVE__UITOA +#define SDL_uitoa _uitoa +#else +#define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) +#endif + +#ifdef HAVE__ULTOA +#define SDL_ultoa _ultoa +#else +extern DECLSPEC char * SDLCALL SDL_ultoa(unsigned long value, char *string, int radix); +#endif + +#ifdef HAVE_STRTOL +#define SDL_strtol strtol +#else +extern DECLSPEC long SDLCALL SDL_strtol(const char *string, char **endp, int base); +#endif + +#ifdef HAVE_STRTOUL +#define SDL_strtoul strtoul +#else +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *string, char **endp, int base); +#endif + +#ifdef SDL_HAS_64BIT_TYPE + +#ifdef HAVE__I64TOA +#define SDL_lltoa _i64toa +#else +extern DECLSPEC char* SDLCALL SDL_lltoa(Sint64 value, char *string, int radix); +#endif + +#ifdef HAVE__UI64TOA +#define SDL_ulltoa _ui64toa +#else +extern DECLSPEC char* SDLCALL SDL_ulltoa(Uint64 value, char *string, int radix); +#endif + +#ifdef HAVE_STRTOLL +#define SDL_strtoll strtoll +#else +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *string, char **endp, int base); +#endif + +#ifdef HAVE_STRTOULL +#define SDL_strtoull strtoull +#else +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *string, char **endp, int base); +#endif + +#endif /* SDL_HAS_64BIT_TYPE */ + +#ifdef HAVE_STRTOD +#define SDL_strtod strtod +#else +extern DECLSPEC double SDLCALL SDL_strtod(const char *string, char **endp); +#endif + +#ifdef HAVE_ATOI +#define SDL_atoi atoi +#else +#define SDL_atoi(X) SDL_strtol(X, NULL, 0) +#endif + +#ifdef HAVE_ATOF +#define SDL_atof atof +#else +#define SDL_atof(X) SDL_strtod(X, NULL) +#endif + +#ifdef HAVE_STRCMP +#define SDL_strcmp strcmp +#else +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +#endif + +#ifdef HAVE_STRNCMP +#define SDL_strncmp strncmp +#else +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); +#endif + +#ifdef HAVE_STRCASECMP +#define SDL_strcasecmp strcasecmp +#elif defined(HAVE__STRICMP) +#define SDL_strcasecmp _stricmp +#else +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); +#endif + +#ifdef HAVE_STRNCASECMP +#define SDL_strncasecmp strncasecmp +#elif defined(HAVE__STRNICMP) +#define SDL_strncasecmp _strnicmp +#else +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen); +#endif + +#ifdef HAVE_SSCANF +#define SDL_sscanf sscanf +#else +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...); +#endif + +#ifdef HAVE_SNPRINTF +#define SDL_snprintf snprintf +#else +extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...); +#endif + +#ifdef HAVE_VSNPRINTF +#define SDL_vsnprintf vsnprintf +#else +extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap); +#endif + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +#ifdef HAVE_ICONV +#define SDL_iconv_t iconv_t +#define SDL_iconv_open iconv_open +#define SDL_iconv_close iconv_close +#else +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +#endif +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); +/* This function converts a string between encodings in one pass, returning a + string that must be freed with SDL_free() or NULL on error. +*/ +extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_stdinc_h */ diff --git a/src/Menge/include/SDL/SDL_syswm.h b/src/Menge/include/SDL/SDL_syswm.h new file mode 100644 index 00000000..010dd1bc --- /dev/null +++ b/src/Menge/include/SDL/SDL_syswm.h @@ -0,0 +1,214 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Include file for SDL custom system window manager hooks */ + +#ifndef _SDL_syswm_h +#define _SDL_syswm_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_version.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Your application has access to a special type of event 'SDL_SYSWMEVENT', + which contains window-manager specific information and arrives whenever + an unhandled window event occurs. This event is ignored by default, but + you can enable it with SDL_EventState() +*/ +#ifdef SDL_PROTOTYPES_ONLY +struct SDL_SysWMinfo; +typedef struct SDL_SysWMinfo SDL_SysWMinfo; +#else + +/* This is the structure for custom window manager events */ +#if defined(SDL_VIDEO_DRIVER_X11) +#if defined(__APPLE__) && defined(__MACH__) +/* conflicts with Quickdraw.h */ +#define Cursor X11Cursor +#endif + +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +/* matches the re-define above */ +#undef Cursor +#endif + +/* These are the various supported subsystems under UNIX */ +typedef enum { + SDL_SYSWM_X11 +} SDL_SYSWM_TYPE; + +/* The UNIX custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + XEvent xevent; + } event; +}; + +/* The UNIX custom window manager information structure. + When this structure is returned, it holds information about which + low level system it is using, and will be one of SDL_SYSWM_TYPE. + */ +typedef struct SDL_SysWMinfo { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + struct { + Display *display; /* The X11 display */ + Window window; /* The X11 display window */ + /* These locking functions should be called around + any X11 functions using the display variable, + but not the gfxdisplay variable. + They lock the event thread, so should not be + called around event functions or from event filters. + */ + void (*lock_func)(void); + void (*unlock_func)(void); + + /* Introduced in SDL 1.0.2 */ + Window fswindow; /* The X11 fullscreen window */ + Window wmwindow; /* The X11 managed input window */ + + /* Introduced in SDL 1.2.12 */ + Display *gfxdisplay; /* The X11 display to which rendering is done */ + } x11; + } info; +} SDL_SysWMinfo; + +#elif defined(SDL_VIDEO_DRIVER_NANOX) +#include + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The windows custom window manager information structure */ +typedef struct SDL_SysWMinfo { + SDL_version version ; + GR_WINDOW_ID window ; /* The display window */ +} SDL_SysWMinfo; + +#elif defined(SDL_VIDEO_DRIVER_WINDIB) || defined(SDL_VIDEO_DRIVER_DDRAW) || defined(SDL_VIDEO_DRIVER_GAPI) +#define WIN32_LEAN_AND_MEAN +#include + +/* The windows custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + HWND hwnd; /* The window for the message */ + UINT msg; /* The type of message */ + WPARAM wParam; /* WORD message parameter */ + LPARAM lParam; /* LONG message parameter */ +}; + +/* The windows custom window manager information structure */ +typedef struct SDL_SysWMinfo { + SDL_version version; + HWND window; /* The Win32 display window */ + HGLRC hglrc; /* The OpenGL context, if any */ +} SDL_SysWMinfo; + +#elif defined(SDL_VIDEO_DRIVER_RISCOS) + +/* RISC OS custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int eventCode; /* The window for the message */ + int pollBlock[64]; +}; + +/* The RISC OS custom window manager information structure */ +typedef struct SDL_SysWMinfo { + SDL_version version; + int wimpVersion; /* Wimp version running under */ + int taskHandle; /* The RISC OS task handle */ + int window; /* The RISC OS display window */ +} SDL_SysWMinfo; + +#elif defined(SDL_VIDEO_DRIVER_PHOTON) +#include +#include + +/* The QNX custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The QNX custom window manager information structure */ +typedef struct SDL_SysWMinfo { + SDL_version version; + int data; +} SDL_SysWMinfo; + +#else + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The generic custom window manager information structure */ +typedef struct SDL_SysWMinfo { + SDL_version version; + int data; +} SDL_SysWMinfo; + +#endif /* video driver type */ + +#endif /* SDL_PROTOTYPES_ONLY */ + +/* Function prototypes */ +/* + * This function gives you custom hooks into the window manager information. + * It fills the structure pointed to by 'info' with custom information and + * returns 1 if the function is implemented. If it's not implemented, or + * the version member of the 'info' structure is invalid, it returns 0. + * + * You typically use this function like this: + * SDL_SysWMInfo info; + * SDL_VERSION(&info.version); + * if ( SDL_GetWMInfo(&info) ) { ... } + */ +extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_syswm_h */ diff --git a/src/Menge/include/SDL/SDL_thread.h b/src/Menge/include/SDL/SDL_thread.h new file mode 100644 index 00000000..403ee462 --- /dev/null +++ b/src/Menge/include/SDL/SDL_thread.h @@ -0,0 +1,119 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_thread_h +#define _SDL_thread_h + +/* Header for the SDL thread management routines + + These are independent of the other SDL routines. +*/ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_mutex.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* Create a thread */ +#if ((defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__)) && !defined(__SYMBIAN32__) +/* + We compile SDL into a DLL on OS/2. This means, that it's the DLL which + creates a new thread for the calling process with the SDL_CreateThread() + API. There is a problem with this, that only the RTL of the SDL.DLL will + be initialized for those threads, and not the RTL of the calling application! + To solve this, we make a little hack here. + We'll always use the caller's _beginthread() and _endthread() APIs to + start a new thread. This way, if it's the SDL.DLL which uses this API, + then the RTL of SDL.DLL will be used to create the new thread, and if it's + the application, then the RTL of the application will be used. + So, in short: + Always use the _beginthread() and _endthread() of the calling runtime library! +*/ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD +#ifndef _WIN32_WCE +#include /* This has _beginthread() and _endthread() defined! */ +#endif + +#ifdef __OS2__ +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void *arg); +typedef void (*pfnSDL_CurrentEndThread)(void); +#elif __GNUC__ +typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall *func)(void *), void *arg, + unsigned, unsigned *threadID); +typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); +#else +typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall *func)(void *), void *arg, + unsigned, unsigned *threadID); +typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); +#endif + +extern DECLSPEC SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); + +#ifdef __OS2__ +#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthread, _endthread) +#elif defined(_WIN32_WCE) +#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL) +#else +#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex) +#endif +#else +extern DECLSPEC SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data); +#endif + +/* Get the 32-bit thread identifier for the current thread */ +extern DECLSPEC Uint32 SDLCALL SDL_ThreadID(void); + +/* Get the 32-bit thread identifier for the specified thread, + equivalent to SDL_ThreadID() if the specified thread is NULL. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetThreadID(SDL_Thread *thread); + +/* Wait for a thread to finish. + The return code for the thread function is placed in the area + pointed to by 'status', if 'status' is not NULL. + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread *thread, int *status); + +/* Forcefully kill a thread without worrying about its state */ +extern DECLSPEC void SDLCALL SDL_KillThread(SDL_Thread *thread); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_thread_h */ diff --git a/src/Menge/include/SDL/SDL_timer.h b/src/Menge/include/SDL/SDL_timer.h new file mode 100644 index 00000000..d21159fe --- /dev/null +++ b/src/Menge/include/SDL/SDL_timer.h @@ -0,0 +1,115 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_timer_h +#define _SDL_timer_h + +/* Header for the SDL time management routines */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the OS scheduler timeslice, in milliseconds */ +#define SDL_TIMESLICE 10 + +/* This is the maximum resolution of the SDL timer on all platforms */ +#define TIMER_RESOLUTION 10 /* Experimentally determined */ + +/* Get the number of milliseconds since the SDL library initialization. + * Note that this value wraps if the program runs for more than ~49 days. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/* Wait a specified number of milliseconds before returning */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/* Function prototype for the timer callback function */ +typedef Uint32 (SDLCALL *SDL_TimerCallback)(Uint32 interval); + +/* Set a callback to run after the specified number of milliseconds has + * elapsed. The callback function is passed the current timer interval + * and returns the next timer interval. If the returned value is the + * same as the one passed in, the periodic alarm continues, otherwise a + * new alarm is scheduled. If the callback returns 0, the periodic alarm + * is cancelled. + * + * To cancel a currently running timer, call SDL_SetTimer(0, NULL); + * + * The timer callback function may run in a different thread than your + * main code, and so shouldn't call any functions from within itself. + * + * The maximum resolution of this timer is 10 ms, which means that if + * you request a 16 ms timer, your callback will run approximately 20 ms + * later on an unloaded system. If you wanted to set a flag signaling + * a frame update at 30 frames per second (every 33 ms), you might set a + * timer for 30 ms: + * SDL_SetTimer((33/10)*10, flag_update); + * + * If you use this function, you need to pass SDL_INIT_TIMER to SDL_Init(). + * + * Under UNIX, you should not use raise or use SIGALRM and this function + * in the same program, as it is implemented using setitimer(). You also + * should not use this function in multi-threaded applications as signals + * to multi-threaded apps have undefined behavior in some implementations. + * + * This function returns 0 if successful, or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_SetTimer(Uint32 interval, SDL_TimerCallback callback); + +/* New timer API, supports multiple timers + * Written by Stephane Peter + */ + +/* Function prototype for the new timer callback function. + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (SDLCALL *SDL_NewTimerCallback)(Uint32 interval, void *param); + +/* Definition of the timer ID type */ +typedef struct _SDL_TimerID *SDL_TimerID; + +/* Add a new timer to the pool of timers already running. + Returns a timer ID, or NULL when an error occurs. + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param); + +/* Remove one of the multiple timers knowing its ID. + * Returns a boolean value indicating success. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID t); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_timer_h */ diff --git a/src/Menge/include/SDL/SDL_ttf.h b/src/Menge/include/SDL/SDL_ttf.h new file mode 100644 index 00000000..10433d59 --- /dev/null +++ b/src/Menge/include/SDL/SDL_ttf.h @@ -0,0 +1,249 @@ +/* + SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* $Id: SDL_ttf.h 5122 2009-10-17 18:16:33Z slouken $ */ + +/* This library is a wrapper around the excellent FreeType 2.0 library, + available at: + http://www.freetype.org/ +*/ + +#ifndef _SDL_TTF_H +#define _SDL_TTF_H + +#include "SDL.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_TTF_MAJOR_VERSION 2 +#define SDL_TTF_MINOR_VERSION 0 +#define SDL_TTF_PATCHLEVEL 10 + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL_ttf library. + */ +#define SDL_TTF_VERSION(X) \ +{ \ + (X)->major = SDL_TTF_MAJOR_VERSION; \ + (X)->minor = SDL_TTF_MINOR_VERSION; \ + (X)->patch = SDL_TTF_PATCHLEVEL; \ +} + +/* Backwards compatibility */ +#define TTF_MAJOR_VERSION SDL_TTF_MAJOR_VERSION +#define TTF_MINOR_VERSION SDL_TTF_MINOR_VERSION +#define TTF_PATCHLEVEL SDL_TTF_PATCHLEVEL +#define TTF_VERSION(X) SDL_TTF_VERSION(X) + +/* This function gets the version of the dynamically linked SDL_ttf library. + it should NOT be used to fill a version structure, instead you should + use the SDL_TTF_VERSION() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL TTF_Linked_Version(void); + +/* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */ +#define UNICODE_BOM_NATIVE 0xFEFF +#define UNICODE_BOM_SWAPPED 0xFFFE + +/* This function tells the library whether UNICODE text is generally + byteswapped. A UNICODE BOM character in a string will override + this setting for the remainder of that string. +*/ +extern DECLSPEC void SDLCALL TTF_ByteSwappedUNICODE(int swapped); + +/* The internal structure containing font information */ +typedef struct _TTF_Font TTF_Font; + +/* Initialize the TTF engine - returns 0 if successful, -1 on error */ +extern DECLSPEC int SDLCALL TTF_Init(void); + +/* Open a font file and create a font of the specified point size. + * Some .fon fonts will have several sizes embedded in the file, so the + * point size becomes the index of choosing which size. If the value + * is too high, the last indexed size will be the default. */ +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndex(const char *file, int ptsize, long index); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index); + +/* Set and retrieve the font style */ +#define TTF_STYLE_NORMAL 0x00 +#define TTF_STYLE_BOLD 0x01 +#define TTF_STYLE_ITALIC 0x02 +#define TTF_STYLE_UNDERLINE 0x04 +#define TTF_STYLE_STRIKETHROUGH 0x08 +extern DECLSPEC int SDLCALL TTF_GetFontStyle(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontStyle(TTF_Font *font, int style); +extern DECLSPEC int SDLCALL TTF_GetFontOutline(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontOutline(TTF_Font *font, int outline); + +/* Set and retrieve FreeType hinter settings */ +#define TTF_HINTING_NORMAL 0 +#define TTF_HINTING_LIGHT 1 +#define TTF_HINTING_MONO 2 +#define TTF_HINTING_NONE 3 +extern DECLSPEC int SDLCALL TTF_GetFontHinting(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontHinting(TTF_Font *font, int hinting); + +/* Get the total height of the font - usually equal to point size */ +extern DECLSPEC int SDLCALL TTF_FontHeight(const TTF_Font *font); + +/* Get the offset from the baseline to the top of the font + This is a positive value, relative to the baseline. + */ +extern DECLSPEC int SDLCALL TTF_FontAscent(const TTF_Font *font); + +/* Get the offset from the baseline to the bottom of the font + This is a negative value, relative to the baseline. + */ +extern DECLSPEC int SDLCALL TTF_FontDescent(const TTF_Font *font); + +/* Get the recommended spacing between lines of text for this font */ +extern DECLSPEC int SDLCALL TTF_FontLineSkip(const TTF_Font *font); + +/* Get/Set whether or not kerning is allowed for this font */ +extern DECLSPEC int SDLCALL TTF_GetFontKerning(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontKerning(TTF_Font *font, int allowed); + +/* Get the number of faces of the font */ +extern DECLSPEC long SDLCALL TTF_FontFaces(const TTF_Font *font); + +/* Get the font face attributes, if any */ +extern DECLSPEC int SDLCALL TTF_FontFaceIsFixedWidth(const TTF_Font *font); +extern DECLSPEC char * SDLCALL TTF_FontFaceFamilyName(const TTF_Font *font); +extern DECLSPEC char * SDLCALL TTF_FontFaceStyleName(const TTF_Font *font); + +/* Check wether a glyph is provided by the font or not */ +extern DECLSPEC int SDLCALL TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch); + +/* Get the metrics (dimensions) of a glyph + To understand what these metrics mean, here is a useful link: + http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html + */ +extern DECLSPEC int SDLCALL TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, + int *minx, int *maxx, + int *miny, int *maxy, int *advance); + +/* Get the dimensions of a rendered string of text */ +extern DECLSPEC int SDLCALL TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int SDLCALL TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int SDLCALL TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h); + +/* Create an 8-bit palettized surface and render the given text at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Solid(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given glyph at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. The glyph is rendered without any padding or + centering in the X direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Solid(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given text at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Shaded(TTF_Font *font, + const Uint16 *text, SDL_Color fg, SDL_Color bg); + +/* Create an 8-bit palettized surface and render the given glyph at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, + Uint16 ch, SDL_Color fg, SDL_Color bg); + +/* Create a 32-bit ARGB surface and render the given text at high quality, + using alpha blending to dither the font with the given color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create a 32-bit ARGB surface and render the given glyph at high quality, + using alpha blending to dither the font with the given color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* For compatibility with previous versions, here are the old functions */ +#define TTF_RenderText(font, text, fg, bg) \ + TTF_RenderText_Shaded(font, text, fg, bg) +#define TTF_RenderUTF8(font, text, fg, bg) \ + TTF_RenderUTF8_Shaded(font, text, fg, bg) +#define TTF_RenderUNICODE(font, text, fg, bg) \ + TTF_RenderUNICODE_Shaded(font, text, fg, bg) + +/* Close an opened font file */ +extern DECLSPEC void SDLCALL TTF_CloseFont(TTF_Font *font); + +/* De-initialize the TTF engine */ +extern DECLSPEC void SDLCALL TTF_Quit(void); + +/* Check if the TTF engine is initialized */ +extern DECLSPEC int SDLCALL TTF_WasInit(void); + +/* We'll use SDL for reporting errors */ +#define TTF_SetError SDL_SetError +#define TTF_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_TTF_H */ diff --git a/src/Menge/include/SDL/SDL_types.h b/src/Menge/include/SDL/SDL_types.h new file mode 100644 index 00000000..853b9ce4 --- /dev/null +++ b/src/Menge/include/SDL/SDL_types.h @@ -0,0 +1,24 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/src/Menge/include/SDL/SDL_version.h b/src/Menge/include/SDL/SDL_version.h new file mode 100644 index 00000000..610ffe67 --- /dev/null +++ b/src/Menge/include/SDL/SDL_version.h @@ -0,0 +1,85 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This header defines the current SDL version */ + +#ifndef _SDL_version_h +#define _SDL_version_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 1 +#define SDL_MINOR_VERSION 2 +#define SDL_PATCHLEVEL 12 + +typedef struct SDL_version { + Uint8 major; + Uint8 minor; + Uint8 patch; +} SDL_version; + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL library. + */ +#define SDL_VERSION(X) \ +{ \ + (X)->major = SDL_MAJOR_VERSION; \ + (X)->minor = SDL_MINOR_VERSION; \ + (X)->patch = SDL_PATCHLEVEL; \ +} + +/* This macro turns the version numbers into a numeric value: + (1,2,3) -> (1203) + This assumes that there will never be more than 100 patchlevels +*/ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/* This is the version number macro for the current SDL version */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) + +/* This macro will evaluate to true if compiled with SDL at least X.Y.Z */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + +/* This function gets the version of the dynamically linked SDL library. + it should NOT be used to fill a version structure, instead you should + use the SDL_Version() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL SDL_Linked_Version(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_version_h */ diff --git a/src/Menge/include/SDL/SDL_video.h b/src/Menge/include/SDL/SDL_video.h new file mode 100644 index 00000000..f6baccee --- /dev/null +++ b/src/Menge/include/SDL/SDL_video.h @@ -0,0 +1,891 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* Header file for access to the SDL raw framebuffer window */ + +#ifndef _SDL_video_h +#define _SDL_video_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Transparency definitions: These define alpha as the opacity of a surface */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 + +/* Useful data types */ +typedef struct SDL_Rect { + Sint16 x, y; + Uint16 w, h; +} SDL_Rect; + +typedef struct SDL_Color { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 unused; +} SDL_Color; +#define SDL_Colour SDL_Color + +typedef struct SDL_Palette { + int ncolors; + SDL_Color *colors; +} SDL_Palette; + +/* Everything in the pixel format structure is read-only */ +typedef struct SDL_PixelFormat { + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + + /* RGB color key information */ + Uint32 colorkey; + /* Alpha value information (per-surface alpha) */ + Uint8 alpha; +} SDL_PixelFormat; + +/* This structure should be treated as read-only, except for 'pixels', + which, if not NULL, contains the raw pixel data for the surface. +*/ +typedef struct SDL_Surface { + Uint32 flags; /* Read-only */ + SDL_PixelFormat *format; /* Read-only */ + int w, h; /* Read-only */ + Uint16 pitch; /* Read-only */ + void *pixels; /* Read-write */ + int offset; /* Private */ + + /* Hardware-specific surface info */ + struct private_hwdata *hwdata; + + /* clipping information */ + SDL_Rect clip_rect; /* Read-only */ + Uint32 unused1; /* for binary compatibility */ + + /* Allow recursive locks */ + Uint32 locked; /* Private */ + + /* info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /* Private */ + + /* format version, bumped at every change to invalidate blit maps */ + unsigned int format_version; /* Private */ + + /* Reference count -- used when freeing surface */ + int refcount; /* Read-mostly */ +} SDL_Surface; + +/* These are the currently supported flags for the SDL_surface */ +/* Available for SDL_CreateRGBSurface() or SDL_SetVideoMode() */ +#define SDL_SWSURFACE 0x00000000 /* Surface is in system memory */ +#define SDL_HWSURFACE 0x00000001 /* Surface is in video memory */ +#define SDL_ASYNCBLIT 0x00000004 /* Use asynchronous blits if possible */ +/* Available for SDL_SetVideoMode() */ +#define SDL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */ +#define SDL_HWPALETTE 0x20000000 /* Surface has exclusive palette */ +#define SDL_DOUBLEBUF 0x40000000 /* Set up double-buffered video mode */ +#define SDL_FULLSCREEN 0x80000000 /* Surface is a full screen display */ +#define SDL_OPENGL 0x00000002 /* Create an OpenGL rendering context */ +#define SDL_OPENGLBLIT 0x0000000A /* Create an OpenGL rendering context and use it for blitting */ +#define SDL_RESIZABLE 0x00000010 /* This video mode may be resized */ +#define SDL_NOFRAME 0x00000020 /* No window caption or edge frame */ +/* Used internally (read-only) */ +#define SDL_HWACCEL 0x00000100 /* Blit uses hardware acceleration */ +#define SDL_SRCCOLORKEY 0x00001000 /* Blit uses a source color key */ +#define SDL_RLEACCELOK 0x00002000 /* Private flag */ +#define SDL_RLEACCEL 0x00004000 /* Surface is RLE encoded */ +#define SDL_SRCALPHA 0x00010000 /* Blit uses source alpha blending */ +#define SDL_PREALLOC 0x01000000 /* Surface uses preallocated memory */ + +/* Evaluates to true if the surface needs to be locked before access */ +#define SDL_MUSTLOCK(surface) \ + (surface->offset || \ + ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0)) + +/* typedef for private surface blitting functions */ +typedef int (*SDL_blit)(struct SDL_Surface *src, SDL_Rect *srcrect, + struct SDL_Surface *dst, SDL_Rect *dstrect); + + +/* Useful for determining the video hardware capabilities */ +typedef struct SDL_VideoInfo { + Uint32 hw_available :1; /* Flag: Can you create hardware surfaces? */ + Uint32 wm_available :1; /* Flag: Can you talk to a window manager? */ + Uint32 UnusedBits1 :6; + Uint32 UnusedBits2 :1; + Uint32 blit_hw :1; /* Flag: Accelerated blits HW --> HW */ + Uint32 blit_hw_CC :1; /* Flag: Accelerated blits with Colorkey */ + Uint32 blit_hw_A :1; /* Flag: Accelerated blits with Alpha */ + Uint32 blit_sw :1; /* Flag: Accelerated blits SW --> HW */ + Uint32 blit_sw_CC :1; /* Flag: Accelerated blits with Colorkey */ + Uint32 blit_sw_A :1; /* Flag: Accelerated blits with Alpha */ + Uint32 blit_fill :1; /* Flag: Accelerated color fill */ + Uint32 UnusedBits3 :16; + Uint32 video_mem; /* The total amount of video memory (in K) */ + SDL_PixelFormat *vfmt; /* Value: The format of the video surface */ + int current_w; /* Value: The current video mode width */ + int current_h; /* Value: The current video mode height */ +} SDL_VideoInfo; + + +/* The most common video overlay formats. + For an explanation of these pixel formats, see: + http://www.webartz.com/fourcc/indexyuv.htm + + For information on the relationship between color spaces, see: + http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html + */ +#define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U (3 planes) */ +#define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V (3 planes) */ +#define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 (1 plane) */ +#define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 (1 plane) */ +#define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 (1 plane) */ + +/* The YUV hardware video overlay */ +typedef struct SDL_Overlay { + Uint32 format; /* Read-only */ + int w, h; /* Read-only */ + int planes; /* Read-only */ + Uint16 *pitches; /* Read-only */ + Uint8 **pixels; /* Read-write */ + + /* Hardware-specific surface info */ + struct private_yuvhwfuncs *hwfuncs; + struct private_yuvhwdata *hwdata; + + /* Special flags */ + Uint32 hw_overlay :1; /* Flag: This overlay hardware accelerated? */ + Uint32 UnusedBits :31; +} SDL_Overlay; + + +/* Public enumeration for setting the OpenGL window attributes. */ +typedef enum { + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_SWAP_CONTROL +} SDL_GLattr; + +/* flags for SDL_SetPalette() */ +#define SDL_LOGPAL 0x01 +#define SDL_PHYSPAL 0x02 + +/* Function prototypes */ + +/* These functions are used internally, and should not be used unless you + * have a specific need to specify the video driver you want to use. + * You should normally use SDL_Init() or SDL_InitSubSystem(). + * + * SDL_VideoInit() initializes the video subsystem -- sets up a connection + * to the window manager, etc, and determines the current video mode and + * pixel format, but does not initialize a window or graphics mode. + * Note that event handling is activated by this routine. + * + * If you use both sound and video in your application, you need to call + * SDL_Init() before opening the sound device, otherwise under Win32 DirectX, + * you won't be able to set full-screen display modes. + */ +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name, Uint32 flags); +extern DECLSPEC void SDLCALL SDL_VideoQuit(void); + +/* This function fills the given character buffer with the name of the + * video driver, and returns a pointer to it if the video driver has + * been initialized. It returns NULL if no driver has been initialized. + */ +extern DECLSPEC char * SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen); + +/* + * This function returns a pointer to the current display surface. + * If SDL is doing format conversion on the display surface, this + * function returns the publicly visible surface, not the real video + * surface. + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_GetVideoSurface(void); + +/* + * This function returns a read-only pointer to information about the + * video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' + * member of the returned structure will contain the pixel format of the + * "best" video mode. + */ +extern DECLSPEC const SDL_VideoInfo * SDLCALL SDL_GetVideoInfo(void); + +/* + * Check to see if a particular video mode is supported. + * It returns 0 if the requested mode is not supported under any bit depth, + * or returns the bits-per-pixel of the closest available mode with the + * given width and height. If this bits-per-pixel is different from the + * one used when setting the video mode, SDL_SetVideoMode() will succeed, + * but will emulate the requested bits-per-pixel with a shadow surface. + * + * The arguments to SDL_VideoModeOK() are the same ones you would pass to + * SDL_SetVideoMode() + */ +extern DECLSPEC int SDLCALL SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags); + +/* + * Return a pointer to an array of available screen dimensions for the + * given format and video flags, sorted largest to smallest. Returns + * NULL if there are no dimensions available for a particular format, + * or (SDL_Rect **)-1 if any dimension is okay for the given format. + * + * If 'format' is NULL, the mode list will be for the format given + * by SDL_GetVideoInfo()->vfmt + */ +extern DECLSPEC SDL_Rect ** SDLCALL SDL_ListModes(SDL_PixelFormat *format, Uint32 flags); + +/* + * Set up a video mode with the specified width, height and bits-per-pixel. + * + * If 'bpp' is 0, it is treated as the current display bits per pixel. + * + * If SDL_ANYFORMAT is set in 'flags', the SDL library will try to set the + * requested bits-per-pixel, but will return whatever video pixel format is + * available. The default is to emulate the requested pixel format if it + * is not natively available. + * + * If SDL_HWSURFACE is set in 'flags', the video surface will be placed in + * video memory, if possible, and you may have to call SDL_LockSurface() + * in order to access the raw framebuffer. Otherwise, the video surface + * will be created in system memory. + * + * If SDL_ASYNCBLIT is set in 'flags', SDL will try to perform rectangle + * updates asynchronously, but you must always lock before accessing pixels. + * SDL will wait for updates to complete before returning from the lock. + * + * If SDL_HWPALETTE is set in 'flags', the SDL library will guarantee + * that the colors set by SDL_SetColors() will be the colors you get. + * Otherwise, in 8-bit mode, SDL_SetColors() may not be able to set all + * of the colors exactly the way they are requested, and you should look + * at the video surface structure to determine the actual palette. + * If SDL cannot guarantee that the colors you request can be set, + * i.e. if the colormap is shared, then the video surface may be created + * under emulation in system memory, overriding the SDL_HWSURFACE flag. + * + * If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set + * a fullscreen video mode. The default is to create a windowed mode + * if the current graphics system has a window manager. + * If the SDL library is able to set a fullscreen video mode, this flag + * will be set in the surface that is returned. + * + * If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up + * two surfaces in video memory and swap between them when you call + * SDL_Flip(). This is usually slower than the normal single-buffering + * scheme, but prevents "tearing" artifacts caused by modifying video + * memory while the monitor is refreshing. It should only be used by + * applications that redraw the entire screen on every update. + * + * If SDL_RESIZABLE is set in 'flags', the SDL library will allow the + * window manager, if any, to resize the window at runtime. When this + * occurs, SDL will send a SDL_VIDEORESIZE event to you application, + * and you must respond to the event by re-calling SDL_SetVideoMode() + * with the requested size (or another size that suits the application). + * + * If SDL_NOFRAME is set in 'flags', the SDL library will create a window + * without any title bar or frame decoration. Fullscreen video modes have + * this flag set automatically. + * + * This function returns the video framebuffer surface, or NULL if it fails. + * + * If you rely on functionality provided by certain video flags, check the + * flags of the returned surface to make sure that functionality is available. + * SDL will fall back to reduced functionality if the exact flags you wanted + * are not available. + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_SetVideoMode + (int width, int height, int bpp, Uint32 flags); + +/* + * Makes sure the given list of rectangles is updated on the given screen. + * If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire + * screen. + * These functions should not be called while 'screen' is locked. + */ +extern DECLSPEC void SDLCALL SDL_UpdateRects + (SDL_Surface *screen, int numrects, SDL_Rect *rects); +extern DECLSPEC void SDLCALL SDL_UpdateRect + (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); + +/* + * On hardware that supports double-buffering, this function sets up a flip + * and returns. The hardware will wait for vertical retrace, and then swap + * video buffers before the next video surface blit or lock will return. + * On hardware that doesn not support double-buffering, this is equivalent + * to calling SDL_UpdateRect(screen, 0, 0, 0, 0); + * The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when + * setting the video mode for this function to perform hardware flipping. + * This function returns 0 if successful, or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface *screen); + +/* + * Set the gamma correction for each of the color channels. + * The gamma values range (approximately) between 0.1 and 10.0 + * + * If this function isn't supported directly by the hardware, it will + * be emulated using gamma ramps, if available. If successful, this + * function returns 0, otherwise it returns -1. + */ +extern DECLSPEC int SDLCALL SDL_SetGamma(float red, float green, float blue); + +/* + * Set the gamma translation table for the red, green, and blue channels + * of the video hardware. Each table is an array of 256 16-bit quantities, + * representing a mapping between the input and output for that channel. + * The input is the index into the array, and the output is the 16-bit + * gamma value at that index, scaled to the output color precision. + * + * You may pass NULL for any of the channels to leave it unchanged. + * If the call succeeds, it will return 0. If the display driver or + * hardware does not support gamma translation, or otherwise fails, + * this function will return -1. + */ +extern DECLSPEC int SDLCALL SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue); + +/* + * Retrieve the current values of the gamma translation tables. + * + * You must pass in valid pointers to arrays of 256 16-bit quantities. + * Any of the pointers may be NULL to ignore that channel. + * If the call succeeds, it will return 0. If the display driver or + * hardware does not support gamma translation, or otherwise fails, + * this function will return -1. + */ +extern DECLSPEC int SDLCALL SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue); + +/* + * Sets a portion of the colormap for the given 8-bit surface. If 'surface' + * is not a palettized surface, this function does nothing, returning 0. + * If all of the colors were set as passed to SDL_SetColors(), it will + * return 1. If not all the color entries were set exactly as given, + * it will return 0, and you should look at the surface palette to + * determine the actual color palette. + * + * When 'surface' is the surface associated with the current display, the + * display colormap will be updated with the requested colors. If + * SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors() + * will always return 1, and the palette is guaranteed to be set the way + * you desire, even if the window colormap has to be warped or run under + * emulation. + */ +extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface *surface, + SDL_Color *colors, int firstcolor, int ncolors); + +/* + * Sets a portion of the colormap for a given 8-bit surface. + * 'flags' is one or both of: + * SDL_LOGPAL -- set logical palette, which controls how blits are mapped + * to/from the surface, + * SDL_PHYSPAL -- set physical palette, which controls how pixels look on + * the screen + * Only screens have physical palettes. Separate change of physical/logical + * palettes is only possible if the screen has SDL_HWPALETTE set. + * + * The return value is 1 if all colours could be set as requested, and 0 + * otherwise. + * + * SDL_SetColors() is equivalent to calling this function with + * flags = (SDL_LOGPAL|SDL_PHYSPAL). + */ +extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface *surface, int flags, + SDL_Color *colors, int firstcolor, + int ncolors); + +/* + * Maps an RGB triple to an opaque pixel value for a given pixel format + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGB +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b); + +/* + * Maps an RGBA quadruple to a pixel value for a given pixel format + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a); + +/* + * Maps a pixel value into the RGB components for a given pixel format + */ +extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, + Uint8 *r, Uint8 *g, Uint8 *b); + +/* + * Maps a pixel value into the RGBA components for a given pixel format + */ +extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a); + +/* + * Allocate and free an RGB surface (must be called after SDL_SetVideoMode) + * If the depth is 4 or 8 bits, an empty palette is allocated for the surface. + * If the depth is greater than 8 bits, the pixel format is set using the + * flags '[RGB]mask'. + * If the function runs out of memory, it will return NULL. + * + * The 'flags' tell what kind of surface to create. + * SDL_SWSURFACE means that the surface should be created in system memory. + * SDL_HWSURFACE means that the surface should be created in video memory, + * with the same format as the display surface. This is useful for surfaces + * that will not change much, to take advantage of hardware acceleration + * when being blitted to the display surface. + * SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with + * this surface, but you must always lock it before accessing the pixels. + * SDL will wait for current blits to finish before returning from the lock. + * SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits. + * If the hardware supports acceleration of colorkey blits between + * two surfaces in video memory, SDL will try to place the surface in + * video memory. If this isn't possible or if there is no hardware + * acceleration available, the surface will be placed in system memory. + * SDL_SRCALPHA means that the surface will be used for alpha blits and + * if the hardware supports hardware acceleration of alpha blits between + * two surfaces in video memory, to place the surface in video memory + * if possible, otherwise it will be placed in system memory. + * If the surface is created in video memory, blits will be _much_ faster, + * but the surface format must be identical to the video surface format, + * and the only way to access the pixels member of the surface is to use + * the SDL_LockSurface() and SDL_UnlockSurface() calls. + * If the requested surface actually resides in video memory, SDL_HWSURFACE + * will be set in the flags member of the returned surface. If for some + * reason the surface could not be placed in video memory, it will not have + * the SDL_HWSURFACE flag set, and will be created in system memory instead. + */ +#define SDL_AllocSurface SDL_CreateRGBSurface +extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface); + +/* + * SDL_LockSurface() sets up a surface for directly accessing the pixels. + * Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write + * to and read from 'surface->pixels', using the pixel format stored in + * 'surface->format'. Once you are done accessing the surface, you should + * use SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates + * to 0, then you can read and write to the surface at any time, and the + * pixel format of the surface will not change. In particular, if the + * SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you + * will not need to lock the display surface before accessing it. + * + * No operating system or library calls should be made between lock/unlock + * pairs, as critical system locks may be held during this time. + * + * SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface *surface); +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface); + +/* + * Load a surface from a seekable SDL data source (memory or file.) + * If 'freesrc' is non-zero, the source will be closed after being read. + * Returns the new surface, or NULL if there was an error. + * The new surface should be freed with SDL_FreeSurface(). + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_LoadBMP_RW(SDL_RWops *src, int freesrc); + +/* Convenience macro -- load a surface from a file */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/* + * Save a surface to a seekable SDL data source (memory or file.) + * If 'freedst' is non-zero, the source will be closed after being written. + * Returns 0 if successful or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface *surface, SDL_RWops *dst, int freedst); + +/* Convenience macro -- save a surface to a file */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/* + * Sets the color key (transparent pixel) in a blittable surface. + * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), + * 'key' will be the transparent pixel in the source image of a blit. + * SDL_RLEACCEL requests RLE acceleration for the surface if present, + * and removes RLE acceleration if absent. + * If 'flag' is 0, this function clears any current color key. + * This function returns 0, or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey + (SDL_Surface *surface, Uint32 flag, Uint32 key); + +/* + * This function sets the alpha value for the entire surface, as opposed to + * using the alpha component of each pixel. This value measures the range + * of transparency of the surface, 0 being completely transparent to 255 + * being completely opaque. An 'alpha' value of 255 causes blits to be + * opaque, the source pixels copied to the destination (the default). Note + * that per-surface alpha can be combined with colorkey transparency. + * + * If 'flag' is 0, alpha blending is disabled for the surface. + * If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. + * OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the + * surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. + * + * The 'alpha' parameter is ignored for surfaces that have an alpha channel. + */ +extern DECLSPEC int SDLCALL SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); + +/* + * Sets the clipping rectangle for the destination surface in a blit. + * + * If the clip rectangle is NULL, clipping will be disabled. + * If the clip rectangle doesn't intersect the surface, the function will + * return SDL_FALSE and blits will be completely clipped. Otherwise the + * function returns SDL_TRUE and blits to the surface will be clipped to + * the intersection of the surface area and the clipping rectangle. + * + * Note that blits are automatically clipped to the edges of the source + * and destination surfaces. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect); + +/* + * Gets the clipping rectangle for the destination surface in a blit. + * 'rect' must be a pointer to a valid rectangle which will be filled + * with the correct values. + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect); + +/* + * Creates a new surface of the specified format, and then copies and maps + * the given surface to it so the blit of the converted surface will be as + * fast as possible. If this function fails, it returns NULL. + * + * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those + * semantics. You can also pass SDL_RLEACCEL in the flags parameter and + * SDL will try to RLE accelerate colorkey and alpha blits in the resulting + * surface. + * + * This function is used internally by SDL_DisplayFormat(). + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_ConvertSurface + (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags); + +/* + * This performs a fast blit from the source surface to the destination + * surface. It assumes that the source and destination rectangles are + * the same size. If either 'srcrect' or 'dstrect' are NULL, the entire + * surface (src or dst) is copied. The final blit rectangles are saved + * in 'srcrect' and 'dstrect' after all clipping is performed. + * If the blit is successful, it returns 0, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without alpha and colorkey + * are defined as follows: + * + * RGBA->RGB: + * SDL_SRCALPHA set: + * alpha-blend (using alpha-channel). + * SDL_SRCCOLORKEY ignored. + * SDL_SRCALPHA not set: + * copy RGB. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * + * RGB->RGBA: + * SDL_SRCALPHA set: + * alpha-blend (using the source per-surface alpha value); + * set destination alpha to opaque. + * SDL_SRCALPHA not set: + * copy RGB, set destination alpha to source per-surface alpha value. + * both: + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. + * + * RGBA->RGBA: + * SDL_SRCALPHA set: + * alpha-blend (using the source alpha channel) the RGB values; + * leave destination alpha untouched. [Note: is this correct?] + * SDL_SRCCOLORKEY ignored. + * SDL_SRCALPHA not set: + * copy all of RGBA to the destination. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * + * RGB->RGB: + * SDL_SRCALPHA set: + * alpha-blend (using the source per-surface alpha value). + * SDL_SRCALPHA not set: + * copy RGB. + * both: + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. + * + * If either of the surfaces were in video memory, and the blit returns -2, + * the video memory was lost, so it should be reloaded with artwork and + * re-blitted: + while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) { + while ( SDL_LockSurface(image) < 0 ) + Sleep(10); + -- Write image pixels to image->pixels -- + SDL_UnlockSurface(image); + } + * This happens under DirectX 5.0 when the system switches away from your + * fullscreen application. The lock will also fail until you have access + * to the video memory again. + */ +/* You should call SDL_BlitSurface() unless you know exactly how SDL + blitting works internally and how to use the other blit functions. +*/ +#define SDL_BlitSurface SDL_UpperBlit + +/* This is the public blit function, SDL_BlitSurface(), and it performs + rectangle validation and clipping before passing it to SDL_LowerBlit() +*/ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +/* This is a semi-private blit function and it performs low-level surface + blitting only. +*/ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + +/* + * This function performs a fast fill of the given rectangle with 'color' + * The given rectangle is clipped to the destination surface clip area + * and the final fill rectangle is saved in the passed in pointer. + * If 'dstrect' is NULL, the whole surface will be filled with 'color' + * The color should be a pixel of the format used by the surface, and + * can be generated by the SDL_MapRGB() function. + * This function returns 0 on success, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); + +/* + * This function takes a surface and copies it to a new surface of the + * pixel format and colors of the video framebuffer, suitable for fast + * blitting onto the display surface. It calls SDL_ConvertSurface() + * + * If you want to take advantage of hardware colorkey or alpha blit + * acceleration, you should set the colorkey and alpha value before + * calling this function. + * + * If the conversion fails or runs out of memory, it returns NULL + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_DisplayFormat(SDL_Surface *surface); + +/* + * This function takes a surface and copies it to a new surface of the + * pixel format and colors of the video framebuffer (if possible), + * suitable for fast alpha blitting onto the display surface. + * The new surface will always have an alpha channel. + * + * If you want to take advantage of hardware colorkey or alpha blit + * acceleration, you should set the colorkey and alpha value before + * calling this function. + * + * If the conversion fails or runs out of memory, it returns NULL + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *surface); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* YUV video surface overlay functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* This function creates a video output overlay + Calling the returned surface an overlay is something of a misnomer because + the contents of the display surface underneath the area where the overlay + is shown is undefined - it may be overwritten with the converted YUV data. +*/ +extern DECLSPEC SDL_Overlay * SDLCALL SDL_CreateYUVOverlay(int width, int height, + Uint32 format, SDL_Surface *display); + +/* Lock an overlay for direct access, and unlock it when you are done */ +extern DECLSPEC int SDLCALL SDL_LockYUVOverlay(SDL_Overlay *overlay); +extern DECLSPEC void SDLCALL SDL_UnlockYUVOverlay(SDL_Overlay *overlay); + +/* Blit a video overlay to the display surface. + The contents of the video surface underneath the blit destination are + not defined. + The width and height of the destination rectangle may be different from + that of the overlay, but currently only 2x scaling is supported. +*/ +extern DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect); + +/* Free a video overlay */ +extern DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL_Overlay *overlay); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* OpenGL support functions. */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Dynamically load an OpenGL library, or the default one if path is NULL + * + * If you do this, you need to retrieve all of the GL functions used in + * your program from the dynamic library using SDL_GL_GetProcAddress(). + */ +extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); + +/* + * Get the address of a GL function + */ +extern DECLSPEC void * SDLCALL SDL_GL_GetProcAddress(const char* proc); + +/* + * Set an attribute of the OpenGL subsystem before intialization. + */ +extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/* + * Get an attribute of the OpenGL subsystem from the windowing + * interface, such as glX. This is of course different from getting + * the values from SDL's internal OpenGL subsystem, which only + * stores the values you request before initialization. + * + * Developers should track the values they pass into SDL_GL_SetAttribute + * themselves if they want to retrieve these values. + */ +extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int* value); + +/* + * Swap the OpenGL buffers, if double-buffering is supported. + */ +extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void); + +/* + * Internal functions that should not be called unless you have read + * and understood the source code for these functions. + */ +extern DECLSPEC void SDLCALL SDL_GL_UpdateRects(int numrects, SDL_Rect* rects); +extern DECLSPEC void SDLCALL SDL_GL_Lock(void); +extern DECLSPEC void SDLCALL SDL_GL_Unlock(void); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* These functions allow interaction with the window manager, if any. */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Sets/Gets the title and icon text of the display window (UTF-8 encoded) + */ +extern DECLSPEC void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon); +extern DECLSPEC void SDLCALL SDL_WM_GetCaption(char **title, char **icon); + +/* + * Sets the icon for the display window. + * This function must be called before the first call to SDL_SetVideoMode(). + * It takes an icon surface, and a mask in MSB format. + * If 'mask' is NULL, the entire icon surface will be used as the icon. + */ +extern DECLSPEC void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); + +/* + * This function iconifies the window, and returns 1 if it succeeded. + * If the function succeeds, it generates an SDL_APPACTIVE loss event. + * This function is a noop and returns 0 in non-windowed environments. + */ +extern DECLSPEC int SDLCALL SDL_WM_IconifyWindow(void); + +/* + * Toggle fullscreen mode without changing the contents of the screen. + * If the display surface does not require locking before accessing + * the pixel information, then the memory pointers will not change. + * + * If this function was able to toggle fullscreen mode (change from + * running in a window to fullscreen, or vice-versa), it will return 1. + * If it is not implemented, or fails, it returns 0. + * + * The next call to SDL_SetVideoMode() will set the mode fullscreen + * attribute based on the flags parameter - if SDL_FULLSCREEN is not + * set, then the display will be windowed by default where supported. + * + * This is currently only implemented in the X11 video driver. + */ +extern DECLSPEC int SDLCALL SDL_WM_ToggleFullScreen(SDL_Surface *surface); + +/* + * This function allows you to set and query the input grab state of + * the application. It returns the new input grab state. + */ +typedef enum { + SDL_GRAB_QUERY = -1, + SDL_GRAB_OFF = 0, + SDL_GRAB_ON = 1, + SDL_GRAB_FULLSCREEN /* Used internally */ +} SDL_GrabMode; +/* + * Grabbing means that the mouse is confined to the application window, + * and nearly all keyboard input is passed directly to the application, + * and not interpreted by a window manager, if any. + */ +extern DECLSPEC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode); + +/* Not in public API at the moment - do not use! */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_video_h */ diff --git a/src/Menge/include/SDL/begin_code.h b/src/Menge/include/SDL/begin_code.h new file mode 100644 index 00000000..b03787f4 --- /dev/null +++ b/src/Menge/include/SDL/begin_code.h @@ -0,0 +1,156 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This file sets things up for C dynamic library function definitions, + static inlined functions, and structures aligned at 4-byte alignment. + If you don't like ugly C preprocessor code, don't look at this file. :) +*/ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__BEOS__) +# if defined(__GNUC__) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(export) +# endif +# elif defined(__WIN32__) +# ifdef __BORLANDC__ +# ifdef BUILD_SDL +# define DECLSPEC +# else +# define DECLSPEC __declspec(dllimport) +# endif +# else +# define DECLSPEC __declspec(dllexport) +# endif +# elif defined(__OS2__) +# ifdef __WATCOMC__ +# ifdef BUILD_SDL +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# else +# define DECLSPEC +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if defined(__WIN32__) && !defined(__GNUC__) +#define SDLCALL __cdecl +#else +#ifdef __OS2__ +/* But on OS/2, we use the _System calling convention */ +/* to be compatible with every compiler */ +#define SDLCALL _System +#else +#define SDLCALL +#endif +#endif +#endif /* SDLCALL */ + +#ifdef __SYMBIAN32__ +#ifndef EKA2 +#undef DECLSPEC +#define DECLSPEC +#elif !defined(__WINS__) +#undef DECLSPEC +#define DECLSPEC __declspec(dllexport) +#endif //EKA2 +#endif //__SYMBIAN32__ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(push,4) +#elif (defined(__MWERKS__) && defined(__MACOS__)) +#pragma options align=mac68k4byte +#pragma enumsalwaysint on +#endif /* Compiler needs structure packing set */ + +/* Set up compiler-specific options for inlining functions */ +#ifndef SDL_INLINE_OKAY +#ifdef __GNUC__ +#define SDL_INLINE_OKAY +#else +/* Add any special compiler-specific cases here */ +#if defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) || defined(__EABI__) +#ifndef __inline__ +#define __inline__ __inline +#endif +#define SDL_INLINE_OKAY +#else +#if !defined(__MRC__) && !defined(_SGI_SOURCE) +#ifndef __inline__ +#define __inline__ inline +#endif +#define SDL_INLINE_OKAY +#endif /* Not a funky compiler */ +#endif /* Visual C++ */ +#endif /* GNU C */ +#endif /* SDL_INLINE_OKAY */ + +/* If inlining isn't supported, remove "__inline__", turning static + inlined functions into static functions (resulting in code bloat + in all files which include the offending header files) +*/ +#ifndef SDL_INLINE_OKAY +#define __inline__ +#endif + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ diff --git a/src/Menge/include/SDL/close_code.h b/src/Menge/include/SDL/close_code.h new file mode 100644 index 00000000..afbb6504 --- /dev/null +++ b/src/Menge/include/SDL/close_code.h @@ -0,0 +1,41 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* This file reverses the effects of begin_code.h and should be included + after you finish any function and structure declarations in your headers +*/ + +#undef _begin_code_h + +/* Reset structure packing at previous byte alignment */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__WATCOMC__) || defined(__BORLANDC__) +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#if (defined(__MWERKS__) && defined(__MACOS__)) +#pragma options align=reset +#pragma enumsalwaysint reset +#else +#pragma pack(pop) +#endif +#endif /* Compiler needs structure packing set */ + diff --git a/src/Menge/include/macros.h b/src/Menge/include/macros.h new file mode 100644 index 00000000..44071e92 --- /dev/null +++ b/src/Menge/include/macros.h @@ -0,0 +1,92 @@ +/* + * macros.h + * + * Created on: Oct 8, 2012 + * Author: piccolo + */ + +#ifndef MACROS_H_ +#define MACROS_H_ + +#ifdef _WIN32 + #include + #define HASH_MAP stdext::hash_map +#else + #include + #define HASH_MAP std::tr1::unordered_map +#endif + +#ifndef _MSC_VER + +#include +#include + + +//FIXME: this should be handle automatically by cmake +#define sprintf_s(buffer, buffer_size, stringbuffer, ...) (snprintf(buffer,buffer_size ,stringbuffer, __VA_ARGS__)) +#define sscanf_s(buffer, buffer_size, stringbuffer, ...) (snprintf(buffer,buffer_size ,stringbuffer, __VA_ARGS__)) + +//typedef long long __int64; + +#ifndef DWORD +#define WINAPI +typedef unsigned long DWORD; +typedef short WCHAR; +typedef void * HANDLE; +//#define MAX_PATH PATH_MAX +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned int BOOL; +#endif + +#ifdef UNICODE + +#define _tcslen wcslen +#define _tcscpy wcscpy +#define _tcscpy_s wcscpy_s +#define _tcsncpy wcsncpy +#define _tcsncpy_s wcsncpy_s +#define _tcscat wcscat +#define _tcscat_s wcscat_s +#define _tcsupr wcsupr +#define _tcsupr_s wcsupr_s +#define _tcslwr wcslwr +#define _tcslwr_s wcslwr_s +#define _stprintf_s swprintf_s +#define _stprintf swprintf +#define _tprintf wprintf +#define _vstprintf_s vswprintf_s +#define _vstprintf vswprintf +#define _tscanf wscanf +#define TCHAR wchar_t + +#else + +#define _tcslen strlen +#define _tcscpy strcpy +#define _tcscpy_s strcpy_s +#define _tcsncpy strncpy +#define _tcsncpy_s strncpy_s +#define _tcscat strcat +#define _tcscat_s strcat_s +#define _tcsupr strupr +#define _tcsupr_s strupr_s +#define _tcslwr strlwr +#define _tcslwr_s strlwr_s +#define _stprintf_s sprintf_s +#define _stprintf sprintf +#define _tprintf printf +#define _vstprintf_s vsprintf_s +#define _vstprintf vsprintf +#define _tscanf scanf +#define TCHAR char + +#endif + +#else // _MSC_VER + +//#define snprintf sprintf_s + +#endif // _MSC_VER + +#endif /* MACROS_H_ */ diff --git a/src/Menge/include/png.h b/src/Menge/include/png.h new file mode 100644 index 00000000..b58c4586 --- /dev/null +++ b/src/Menge/include/png.h @@ -0,0 +1,3808 @@ +/* png.h - header file for PNG reference library + * + * libpng version 1.2.49 - March 29, 2012 + * Copyright (c) 1998-2012 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license (See LICENSE, below) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.49 - March 29, 2012: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 10.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.2.13beta1 13 10213 12.so.0.13[.0] + * 1.0.21 10 10021 10.so.0.21[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.2.14beta1-2 13 10214 12.so.0.14[.0] + * 1.0.22rc1 10 10022 10.so.0.22[.0] + * 1.2.14rc1 13 10214 12.so.0.14[.0] + * 1.0.22 10 10022 10.so.0.22[.0] + * 1.2.14 13 10214 12.so.0.14[.0] + * 1.2.15beta1-6 13 10215 12.so.0.15[.0] + * 1.0.23rc1-5 10 10023 10.so.0.23[.0] + * 1.2.15rc1-5 13 10215 12.so.0.15[.0] + * 1.0.23 10 10023 10.so.0.23[.0] + * 1.2.15 13 10215 12.so.0.15[.0] + * 1.2.16beta1-2 13 10216 12.so.0.16[.0] + * 1.2.16rc1 13 10216 12.so.0.16[.0] + * 1.0.24 10 10024 10.so.0.24[.0] + * 1.2.16 13 10216 12.so.0.16[.0] + * 1.2.17beta1-2 13 10217 12.so.0.17[.0] + * 1.0.25rc1 10 10025 10.so.0.25[.0] + * 1.2.17rc1-3 13 10217 12.so.0.17[.0] + * 1.0.25 10 10025 10.so.0.25[.0] + * 1.2.17 13 10217 12.so.0.17[.0] + * 1.0.26 10 10026 10.so.0.26[.0] + * 1.2.18 13 10218 12.so.0.18[.0] + * 1.2.19beta1-31 13 10219 12.so.0.19[.0] + * 1.0.27rc1-6 10 10027 10.so.0.27[.0] + * 1.2.19rc1-6 13 10219 12.so.0.19[.0] + * 1.0.27 10 10027 10.so.0.27[.0] + * 1.2.19 13 10219 12.so.0.19[.0] + * 1.2.20beta01-04 13 10220 12.so.0.20[.0] + * 1.0.28rc1-6 10 10028 10.so.0.28[.0] + * 1.2.20rc1-6 13 10220 12.so.0.20[.0] + * 1.0.28 10 10028 10.so.0.28[.0] + * 1.2.20 13 10220 12.so.0.20[.0] + * 1.2.21beta1-2 13 10221 12.so.0.21[.0] + * 1.2.21rc1-3 13 10221 12.so.0.21[.0] + * 1.0.29 10 10029 10.so.0.29[.0] + * 1.2.21 13 10221 12.so.0.21[.0] + * 1.2.22beta1-4 13 10222 12.so.0.22[.0] + * 1.0.30rc1 10 10030 10.so.0.30[.0] + * 1.2.22rc1 13 10222 12.so.0.22[.0] + * 1.0.30 10 10030 10.so.0.30[.0] + * 1.2.22 13 10222 12.so.0.22[.0] + * 1.2.23beta01-05 13 10223 12.so.0.23[.0] + * 1.2.23rc01 13 10223 12.so.0.23[.0] + * 1.2.23 13 10223 12.so.0.23[.0] + * 1.2.24beta01-02 13 10224 12.so.0.24[.0] + * 1.2.24rc01 13 10224 12.so.0.24[.0] + * 1.2.24 13 10224 12.so.0.24[.0] + * 1.2.25beta01-06 13 10225 12.so.0.25[.0] + * 1.2.25rc01-02 13 10225 12.so.0.25[.0] + * 1.0.31 10 10031 10.so.0.31[.0] + * 1.2.25 13 10225 12.so.0.25[.0] + * 1.2.26beta01-06 13 10226 12.so.0.26[.0] + * 1.2.26rc01 13 10226 12.so.0.26[.0] + * 1.2.26 13 10226 12.so.0.26[.0] + * 1.0.32 10 10032 10.so.0.32[.0] + * 1.2.27beta01-06 13 10227 12.so.0.27[.0] + * 1.2.27rc01 13 10227 12.so.0.27[.0] + * 1.0.33 10 10033 10.so.0.33[.0] + * 1.2.27 13 10227 12.so.0.27[.0] + * 1.0.34 10 10034 10.so.0.34[.0] + * 1.2.28 13 10228 12.so.0.28[.0] + * 1.2.29beta01-03 13 10229 12.so.0.29[.0] + * 1.2.29rc01 13 10229 12.so.0.29[.0] + * 1.0.35 10 10035 10.so.0.35[.0] + * 1.2.29 13 10229 12.so.0.29[.0] + * 1.0.37 10 10037 10.so.0.37[.0] + * 1.2.30beta01-04 13 10230 12.so.0.30[.0] + * 1.0.38rc01-08 10 10038 10.so.0.38[.0] + * 1.2.30rc01-08 13 10230 12.so.0.30[.0] + * 1.0.38 10 10038 10.so.0.38[.0] + * 1.2.30 13 10230 12.so.0.30[.0] + * 1.0.39rc01-03 10 10039 10.so.0.39[.0] + * 1.2.31rc01-03 13 10231 12.so.0.31[.0] + * 1.0.39 10 10039 10.so.0.39[.0] + * 1.2.31 13 10231 12.so.0.31[.0] + * 1.2.32beta01-02 13 10232 12.so.0.32[.0] + * 1.0.40rc01 10 10040 10.so.0.40[.0] + * 1.2.32rc01 13 10232 12.so.0.32[.0] + * 1.0.40 10 10040 10.so.0.40[.0] + * 1.2.32 13 10232 12.so.0.32[.0] + * 1.2.33beta01-02 13 10233 12.so.0.33[.0] + * 1.2.33rc01-02 13 10233 12.so.0.33[.0] + * 1.0.41rc01 10 10041 10.so.0.41[.0] + * 1.2.33 13 10233 12.so.0.33[.0] + * 1.0.41 10 10041 10.so.0.41[.0] + * 1.2.34beta01-07 13 10234 12.so.0.34[.0] + * 1.0.42rc01 10 10042 10.so.0.42[.0] + * 1.2.34rc01 13 10234 12.so.0.34[.0] + * 1.0.42 10 10042 10.so.0.42[.0] + * 1.2.34 13 10234 12.so.0.34[.0] + * 1.2.35beta01-03 13 10235 12.so.0.35[.0] + * 1.0.43rc01-02 10 10043 10.so.0.43[.0] + * 1.2.35rc01-02 13 10235 12.so.0.35[.0] + * 1.0.43 10 10043 10.so.0.43[.0] + * 1.2.35 13 10235 12.so.0.35[.0] + * 1.2.36beta01-05 13 10236 12.so.0.36[.0] + * 1.2.36rc01 13 10236 12.so.0.36[.0] + * 1.0.44 10 10044 10.so.0.44[.0] + * 1.2.36 13 10236 12.so.0.36[.0] + * 1.2.37beta01-03 13 10237 12.so.0.37[.0] + * 1.2.37rc01 13 10237 12.so.0.37[.0] + * 1.2.37 13 10237 12.so.0.37[.0] + * 1.0.45 10 10045 12.so.0.45[.0] + * 1.0.46 10 10046 10.so.0.46[.0] + * 1.2.38beta01 13 10238 12.so.0.38[.0] + * 1.2.38rc01-03 13 10238 12.so.0.38[.0] + * 1.0.47 10 10047 10.so.0.47[.0] + * 1.2.38 13 10238 12.so.0.38[.0] + * 1.2.39beta01-05 13 10239 12.so.0.39[.0] + * 1.2.39rc01 13 10239 12.so.0.39[.0] + * 1.0.48 10 10048 10.so.0.48[.0] + * 1.2.39 13 10239 12.so.0.39[.0] + * 1.2.40beta01 13 10240 12.so.0.40[.0] + * 1.2.40rc01 13 10240 12.so.0.40[.0] + * 1.0.49 10 10049 10.so.0.49[.0] + * 1.2.40 13 10240 12.so.0.40[.0] + * 1.2.41beta01-18 13 10241 12.so.0.41[.0] + * 1.0.51rc01 10 10051 10.so.0.51[.0] + * 1.2.41rc01-03 13 10241 12.so.0.41[.0] + * 1.0.51 10 10051 10.so.0.51[.0] + * 1.2.41 13 10241 12.so.0.41[.0] + * 1.2.42beta01-02 13 10242 12.so.0.42[.0] + * 1.2.42rc01-05 13 10242 12.so.0.42[.0] + * 1.0.52 10 10052 10.so.0.52[.0] + * 1.2.42 13 10242 12.so.0.42[.0] + * 1.2.43beta01-05 13 10243 12.so.0.43[.0] + * 1.0.53rc01-02 10 10053 10.so.0.53[.0] + * 1.2.43rc01-02 13 10243 12.so.0.43[.0] + * 1.0.53 10 10053 10.so.0.53[.0] + * 1.2.43 13 10243 12.so.0.43[.0] + * 1.2.44beta01-03 13 10244 12.so.0.44[.0] + * 1.2.44rc01-03 13 10244 12.so.0.44[.0] + * 1.2.44 13 10244 12.so.0.44[.0] + * 1.2.45beta01-03 13 10245 12.so.0.45[.0] + * 1.0.55rc01 10 10055 10.so.0.55[.0] + * 1.2.45rc01 13 10245 12.so.0.45[.0] + * 1.0.55 10 10055 10.so.0.55[.0] + * 1.2.45 13 10245 12.so.0.45[.0] + * 1.2.46rc01-02 13 10246 12.so.0.46[.0] + * 1.0.56 10 10056 10.so.0.56[.0] + * 1.2.46 13 10246 12.so.0.46[.0] + * 1.2.47beta01 13 10247 12.so.0.47[.0] + * 1.2.47rc01 13 10247 12.so.0.47[.0] + * 1.0.57rc01 10 10057 10.so.0.57[.0] + * 1.2.47 13 10247 12.so.0.47[.0] + * 1.0.57 10 10057 10.so.0.57[.0] + * 1.2.48beta01 13 10248 12.so.0.48[.0] + * 1.2.48rc01-02 13 10248 12.so.0.48[.0] + * 1.0.58 10 10058 10.so.0.58[.0] + * 1.2.48 13 10248 12.so.0.48[.0] + * 1.2.49rc01 13 10249 12.so.0.49[.0] + * 1.0.59 10 10059 10.so.0.59[.0] + * 1.2.49 13 10249 12.so.0.49[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO Specification, + * defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only, deprecated */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE 0x0800 /* write only */ +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.2.41 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn PNG_DEPSTRUCT; /* function for printing errors and aborting */ + png_error_ptr warning_fn PNG_DEPSTRUCT; /* function for printing warnings */ + png_voidp error_ptr PNG_DEPSTRUCT; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn PNG_DEPSTRUCT; /* function for writing output data */ + png_rw_ptr read_data_fn PNG_DEPSTRUCT; /* function for reading input data */ + png_voidp io_ptr PNG_DEPSTRUCT; /* ptr to application struct for I/O functions */ + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr read_user_transform_fn PNG_DEPSTRUCT; /* user read transform */ +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr write_user_transform_fn PNG_DEPSTRUCT; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr PNG_DEPSTRUCT; /* user supplied struct for user transform */ + png_byte user_transform_depth PNG_DEPSTRUCT; /* bit depth of user transformed pixels */ + png_byte user_transform_channels PNG_DEPSTRUCT; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode PNG_DEPSTRUCT; /* tells us where we are in the PNG file */ + png_uint_32 flags PNG_DEPSTRUCT; /* flags indicating various things to libpng */ + png_uint_32 transformations PNG_DEPSTRUCT; /* which transformations to perform */ + + z_stream zstream PNG_DEPSTRUCT; /* pointer to decompression structure (below) */ + png_bytep zbuf PNG_DEPSTRUCT; /* buffer for zlib */ + png_size_t zbuf_size PNG_DEPSTRUCT; /* size of zbuf */ + int zlib_level PNG_DEPSTRUCT; /* holds zlib compression level */ + int zlib_method PNG_DEPSTRUCT; /* holds zlib compression method */ + int zlib_window_bits PNG_DEPSTRUCT; /* holds zlib compression window bits */ + int zlib_mem_level PNG_DEPSTRUCT; /* holds zlib compression memory level */ + int zlib_strategy PNG_DEPSTRUCT; /* holds zlib compression strategy */ + + png_uint_32 width PNG_DEPSTRUCT; /* width of image in pixels */ + png_uint_32 height PNG_DEPSTRUCT; /* height of image in pixels */ + png_uint_32 num_rows PNG_DEPSTRUCT; /* number of rows in current pass */ + png_uint_32 usr_width PNG_DEPSTRUCT; /* width of row at start of write */ + png_uint_32 rowbytes PNG_DEPSTRUCT; /* size of row in bytes */ +#if 0 /* Replaced with the following in libpng-1.2.43 */ + png_size_t irowbytes PNG_DEPSTRUCT; +#endif +/* Added in libpng-1.2.43 */ +#ifdef PNG_USER_LIMITS_SUPPORTED + /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown + * chunks that can be stored (0 means unlimited). + */ + png_uint_32 user_chunk_cache_max PNG_DEPSTRUCT; +#endif + png_uint_32 iwidth PNG_DEPSTRUCT; /* width of current interlaced row in pixels */ + png_uint_32 row_number PNG_DEPSTRUCT; /* current row in interlace pass */ + png_bytep prev_row PNG_DEPSTRUCT; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf PNG_DEPSTRUCT; /* buffer to save current (unfiltered) row */ +#ifndef PNG_NO_WRITE_FILTER + png_bytep sub_row PNG_DEPSTRUCT; /* buffer to save "sub" row when filtering */ + png_bytep up_row PNG_DEPSTRUCT; /* buffer to save "up" row when filtering */ + png_bytep avg_row PNG_DEPSTRUCT; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row PNG_DEPSTRUCT; /* buffer to save "Paeth" row when filtering */ +#endif + png_row_info row_info PNG_DEPSTRUCT; /* used for transformation routines */ + + png_uint_32 idat_size PNG_DEPSTRUCT; /* current IDAT size for read */ + png_uint_32 crc PNG_DEPSTRUCT; /* current chunk CRC value */ + png_colorp palette PNG_DEPSTRUCT; /* palette from the input file */ + png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in palette */ + png_uint_16 num_trans PNG_DEPSTRUCT; /* number of transparency values */ + png_byte chunk_name[5] PNG_DEPSTRUCT; /* null-terminated name of current chunk */ + png_byte compression PNG_DEPSTRUCT; /* file compression type (always 0) */ + png_byte filter PNG_DEPSTRUCT; /* file filter type (always 0) */ + png_byte interlaced PNG_DEPSTRUCT; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass PNG_DEPSTRUCT; /* current interlace pass (0 - 6) */ + png_byte do_filter PNG_DEPSTRUCT; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type PNG_DEPSTRUCT; /* color type of file */ + png_byte bit_depth PNG_DEPSTRUCT; /* bit depth of file */ + png_byte usr_bit_depth PNG_DEPSTRUCT; /* bit depth of users row */ + png_byte pixel_depth PNG_DEPSTRUCT; /* number of bits per pixel */ + png_byte channels PNG_DEPSTRUCT; /* number of channels in file */ + png_byte usr_channels PNG_DEPSTRUCT; /* channels at start of write */ + png_byte sig_bytes PNG_DEPSTRUCT; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler PNG_DEPSTRUCT; /* filler byte for pixel expansion */ +#else + png_uint_16 filler PNG_DEPSTRUCT; /* filler bytes for pixel expansion */ +#endif +#endif + +#ifdef PNG_bKGD_SUPPORTED + png_byte background_gamma_type PNG_DEPSTRUCT; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma PNG_DEPSTRUCT; +# endif + png_color_16 background PNG_DEPSTRUCT; /* background color in screen gamma space */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_color_16 background_1 PNG_DEPSTRUCT; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_flush_ptr output_flush_fn PNG_DEPSTRUCT; /* Function for flushing output */ + png_uint_32 flush_dist PNG_DEPSTRUCT; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows PNG_DEPSTRUCT; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift PNG_DEPSTRUCT; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma PNG_DEPSTRUCT; /* file gamma value */ + float screen_gamma PNG_DEPSTRUCT; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table PNG_DEPSTRUCT; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */ + png_bytep gamma_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table PNG_DEPSTRUCT; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift PNG_DEPSTRUCT; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans PNG_DEPSTRUCT; /* transparency values for paletted files */ + png_color_16 trans_values PNG_DEPSTRUCT; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn PNG_DEPSTRUCT; /* called after each row is decoded */ + png_write_status_ptr write_row_fn PNG_DEPSTRUCT; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn PNG_DEPSTRUCT; /* called after header data fully read */ + png_progressive_row_ptr row_fn PNG_DEPSTRUCT; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn PNG_DEPSTRUCT; /* called after image is complete */ + png_bytep save_buffer_ptr PNG_DEPSTRUCT; /* current location in save_buffer */ + png_bytep save_buffer PNG_DEPSTRUCT; /* buffer for previously read data */ + png_bytep current_buffer_ptr PNG_DEPSTRUCT; /* current location in current_buffer */ + png_bytep current_buffer PNG_DEPSTRUCT; /* buffer for recently used data */ + png_uint_32 push_length PNG_DEPSTRUCT; /* size of current input chunk */ + png_uint_32 skip_length PNG_DEPSTRUCT; /* bytes to skip in input data */ + png_size_t save_buffer_size PNG_DEPSTRUCT; /* amount of data now in save_buffer */ + png_size_t save_buffer_max PNG_DEPSTRUCT; /* total size of save_buffer */ + png_size_t buffer_size PNG_DEPSTRUCT; /* total amount of available input data */ + png_size_t current_buffer_size PNG_DEPSTRUCT; /* amount of data now in current_buffer */ + int process_mode PNG_DEPSTRUCT; /* what push library is currently doing */ + int cur_palette PNG_DEPSTRUCT; /* current push library palette index */ + +# ifdef PNG_TEXT_SUPPORTED + png_size_t current_text_size PNG_DEPSTRUCT; /* current size of text input data */ + png_size_t current_text_left PNG_DEPSTRUCT; /* how much text left to read in input */ + png_charp current_text PNG_DEPSTRUCT; /* current text chunk buffer */ + png_charp current_text_ptr PNG_DEPSTRUCT; /* current location in current_text */ +# endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr PNG_DEPSTRUCT; + png_bytep offset_table PNG_DEPSTRUCT; + png_uint_16 offset_table_number PNG_DEPSTRUCT; + png_uint_16 offset_table_count PNG_DEPSTRUCT; + png_uint_16 offset_table_count_free PNG_DEPSTRUCT; +#endif + +#ifdef PNG_READ_DITHER_SUPPORTED + png_bytep palette_lookup PNG_DEPSTRUCT; /* lookup table for dithering */ + png_bytep dither_index PNG_DEPSTRUCT; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist PNG_DEPSTRUCT; /* histogram */ +#endif + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + png_byte heuristic_method PNG_DEPSTRUCT; /* heuristic for row filter selection */ + png_byte num_prev_filters PNG_DEPSTRUCT; /* number of weights for previous rows */ + png_bytep prev_filters PNG_DEPSTRUCT; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights PNG_DEPSTRUCT; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights PNG_DEPSTRUCT; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs PNG_DEPSTRUCT; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs PNG_DEPSTRUCT; /* 1/relative filter calculation cost */ +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + png_charp time_buffer PNG_DEPSTRUCT; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me PNG_DEPSTRUCT; /* flags items libpng is responsible for freeing */ +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp user_chunk_ptr PNG_DEPSTRUCT; + png_user_chunk_ptr read_user_chunk_fn PNG_DEPSTRUCT; /* user read chunk handler */ +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int num_chunk_list PNG_DEPSTRUCT; + png_bytep chunk_list PNG_DEPSTRUCT; +#endif + +/* New members added in libpng-1.0.3 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status PNG_DEPSTRUCT; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff PNG_DEPSTRUCT; + png_uint_16 rgb_to_gray_green_coeff PNG_DEPSTRUCT; + png_uint_16 rgb_to_gray_blue_coeff PNG_DEPSTRUCT; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted PNG_DEPSTRUCT; +#else + png_uint_32 mng_features_permitted PNG_DEPSTRUCT; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma PNG_DEPSTRUCT; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_byte filter_type PNG_DEPSTRUCT; +#endif + +#ifdef PNG_1_0_X +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size PNG_DEPSTRUCT; +#endif + +/* New members added in libpng-1.2.0 */ +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +# ifndef PNG_1_0_X +# ifdef PNG_MMX_CODE_SUPPORTED + png_byte mmx_bitdepth_threshold PNG_DEPSTRUCT; + png_uint_32 mmx_rowbytes_threshold PNG_DEPSTRUCT; +# endif + png_uint_32 asm_flags PNG_DEPSTRUCT; +# endif +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr PNG_DEPSTRUCT; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn PNG_DEPSTRUCT; /* function for allocating memory */ + png_free_ptr free_fn PNG_DEPSTRUCT; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf PNG_DEPSTRUCT; /* buffer to save current (unfiltered) row */ + +#ifdef PNG_READ_DITHER_SUPPORTED +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort PNG_DEPSTRUCT; /* working sort array */ + png_bytep index_to_palette PNG_DEPSTRUCT; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index PNG_DEPSTRUCT; /* which original index points to this */ + /* palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type PNG_DEPSTRUCT; + +#ifdef PNG_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max PNG_DEPSTRUCT; + png_uint_32 user_height_max PNG_DEPSTRUCT; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk PNG_DEPSTRUCT; +#endif + +/* New members added in libpng-1.2.26 */ + png_uint_32 old_big_row_buf_size PNG_DEPSTRUCT; + png_uint_32 old_prev_row_size PNG_DEPSTRUCT; + +/* New member added in libpng-1.2.30 */ + png_charp chunkdata PNG_DEPSTRUCT; /* buffer for reading chunk data */ + + +}; + + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef png_structp version_1_2_49; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)) PNG_DEPRECATED; + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED; + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED; + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); +#endif + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED; +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED; +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)) PNG_ALLOCATED; + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)) + PNG_DEPRECATED; +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ + png_sizeof(png_info)); +#endif + +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_CONVERT_tIME_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +#ifndef PNG_1_0_X +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)) PNG_DEPRECATED; +#endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +#ifndef PNG_1_0_X +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +#endif +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_16_TO_8_SUPPORTED +/* Strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_READ_DITHER_SUPPORTED +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)) PNG_DEPRECATED; +#endif +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* Optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); +#endif + +/* Write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* Write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* Write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* Writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)) PNG_DEPRECATED; + +/* Free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)) PNG_DEPRECATED; + +/* Set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* Function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* Function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)) PNG_ALLOCATED; + +#ifdef PNG_1_0_X +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)) PNG_ALLOCATED; +#endif + +/* Frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#ifdef PNG_1_0_X +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application + */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)) PNG_ALLOCATED; +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)) PNG_DEPRECATED; + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)) PNG_DEPRECATED; + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +#ifndef PNG_NO_ERROR_TEXT +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)) PNG_NORETURN; + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)) PNG_NORETURN; +#else +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN; +#endif + +#ifndef PNG_NO_WARNINGS +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_NO_WARNINGS */ + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_bKGD_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#ifdef PNG_cHRM_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#ifdef PNG_gAMA_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#ifdef PNG_hIST_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#ifdef PNG_iCCP_SUPPORTED +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#ifdef PNG_sPLT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +#endif + +#ifdef PNG_sCAL_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#ifdef PNG_sCAL_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +/* Provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behaviour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include +#if (PNG_DEBUG > 1) +#ifndef _DEBUG +# define _DEBUG +#endif +#ifndef png_debug +#define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) +#endif +#ifndef png_debug1 +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) +#endif +#ifndef png_debug2 +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) +#endif +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ + +#if (PNG_DEBUG > 1) +/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on non-ISO + * compilers. + */ +# ifdef __STDC__ +# ifndef png_debug +# define png_debug(l,m) \ + { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ + } +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ + } +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ + } +# endif +# else /* __STDC __ */ +# ifndef png_debug +# define png_debug(l,m) \ + { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format); \ + } +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1); \ + } +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1,p2); \ + } +# endif +# endif /* __STDC __ */ +#endif /* (PNG_DEBUG > 1) */ + +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Added to version 1.2.0 */ +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#ifdef PNG_MMX_CODE_SUPPORTED +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 +#endif /* PNG_MMX_CODE_SUPPORTED */ + +#ifndef PNG_1_0_X +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ + +#ifndef PNG_1_0_X +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); +#endif /* PNG_1_0_X */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif + +/* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp + png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp + png_ptr)); +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp + png_ptr)); +#endif +/* Maintainer: Put new public prototypes here ^, in libpng.3, and in + * project defs + */ + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + + +/* Various modes of operation, that are visible to applications because + * they are used for unknown chunk location. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ +#define PNG_HAVE_IEND 0x10 + +#ifdef PNG_INTERNAL + +/* More modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* Flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ +#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ +#define PNG_PREMULTIPLY_ALPHA 0x4000000L /* Added to libpng-1.2.41 */ + /* by volker */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +/* Flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* Flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* Save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ + (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + * ideal-delta..ideal+delta. Each argument is evaluated twice. + * "ideal" and "delta" should be constants, normally simple + * integers, "value" a variable. Added to libpng-1.2.6 JB + */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* Place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8]; +#else +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)) + PNG_DEPRECATED; +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)) + PNG_DEPRECATED; +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)) PNG_PRIVATE; + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)) PNG_PRIVATE; + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)) PNG_PRIVATE; + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, + uInt size)) PNG_PRIVATE; + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)) PNG_PRIVATE; + +#ifdef PNG_SIZE_T +/* Function to convert a sizeof an item to png_sizeof item */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)) + PNG_PRIVATE; +#endif + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. + */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)) PNG_PRIVATE; + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)) PNG_PRIVATE; +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)) PNG_PRIVATE; + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)) + PNG_PRIVATE; +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)) PNG_PRIVATE; +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)) PNG_PRIVATE; + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)) PNG_PRIVATE; + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)) PNG_PRIVATE; + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)) PNG_PRIVATE; +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip) + PNG_PRIVATE); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)) PNG_PRIVATE; + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)) PNG_PRIVATE; +#endif + +/* Simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +/* Write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)) PNG_PRIVATE; + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)) PNG_PRIVATE; + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)) PNG_PRIVATE; + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +#ifdef PNG_WRITE_gAMA_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)) + PNG_PRIVATE; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, + png_fixed_point file_gamma)) PNG_PRIVATE; +#endif +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)) PNG_PRIVATE; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)) PNG_PRIVATE; +#endif +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)) PNG_PRIVATE; + /* Note to maintainer: profile should be png_bytep */ +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)) PNG_PRIVATE; +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_tEXt_SUPPORTED +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)) PNG_PRIVATE; +#endif + +#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)) PNG_PRIVATE; +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)) PNG_PRIVATE; +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +#ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)) PNG_PRIVATE; +#endif + +/* Combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)) PNG_PRIVATE; + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)) PNG_PRIVATE; + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)) PNG_PRIVATE; +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)) PNG_PRIVATE; +#endif + +/* Unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, + int filter)) PNG_PRIVATE; + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)) PNG_PRIVATE; + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)) PNG_PRIVATE; +/* Finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* Initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE; +/* Optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; + +/* These are the functions that do the transformations */ +#ifdef PNG_READ_FILLER_SUPPORTED +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)) PNG_PRIVATE; +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_PACK_SUPPORTED +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)) PNG_PRIVATE; +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_16_TO_8_SUPPORTED +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_DITHER_SUPPORTED +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, + png_bytep dither_lookup)) PNG_PRIVATE; + +# ifdef PNG_CORRECT_PALETTE_SUPPORTED +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)) PNG_PRIVATE; +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)) PNG_PRIVATE; +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +#ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)) PNG_PRIVATE; +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)) PNG_PRIVATE; +#endif +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, + int num_trans)) PNG_PRIVATE; +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)) PNG_PRIVATE; +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* Decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#ifdef PNG_READ_bKGD_SUPPORTED +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_iTXt_SUPPORTED +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_sRGB_SUPPORTED +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)) PNG_PRIVATE; +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE; + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)) PNG_PRIVATE; + +/* Handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations + PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_do_write_transformations + PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +PNG_EXTERN void png_init_read_transformations + PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE; +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, + png_bytep row)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +PNG_EXTERN void png_read_push_finish_row + PNGARG((png_structp png_ptr)) PNG_PRIVATE; +#ifdef PNG_READ_tEXt_SUPPORTED +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +#endif +#ifdef PNG_READ_zTXt_SUPPORTED +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +#endif +#ifdef PNG_READ_iTXt_SUPPORTED +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE; +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)) PNG_PRIVATE; +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)) PNG_PRIVATE; +#endif + +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#ifdef PNG_MMX_CODE_SUPPORTED +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)) PNG_PRIVATE; +#endif +#endif + + +/* The following six functions will be exported in libpng-1.4.0. */ +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* Read the chunk header (length + type name) */ +PNG_EXTERN png_uint_32 png_read_chunk_header + PNGARG((png_structp png_ptr)) PNG_PRIVATE; + +/* Added at libpng version 1.2.34 */ +#ifdef PNG_cHRM_SUPPORTED +PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)) PNG_PRIVATE; +#endif + +#ifdef PNG_cHRM_SUPPORTED +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 */ +PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, + unsigned long *hi_product, unsigned long *lo_product)) PNG_PRIVATE; +#endif +#endif + +/* Added at libpng version 1.2.41 */ +PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type)) PNG_PRIVATE; + +/* Added at libpng version 1.2.41 */ +PNG_EXTERN png_voidp png_calloc PNGARG((png_structp png_ptr, + png_uint_32 size)); + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/src/Menge/include/pngconf.h b/src/Menge/include/pngconf.h new file mode 100644 index 00000000..85d9b2a3 --- /dev/null +++ b/src/Menge/include/pngconf.h @@ -0,0 +1,1665 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.2.49 - March 29, 2012 + * Copyright (c) 1998-2012 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#define PNG_1_2_X + +/* + * PNG_USER_CONFIG has to be defined on the compiler command line. This + * includes the resource compiler for Windows DLL configurations. + */ +#ifdef PNG_USER_CONFIG +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif +#include "pngusr.h" +#endif + +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #define PNG_USER_PRIVATEBUILD + * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." + * #define PNG_USER_DLLFNAME_POSTFIX + * e.g. // private DLL "libpng13gx.dll" + * #define PNG_USER_DLLFNAME_POSTFIX "gx" + * + * The following macros are also at your disposal if you want to complete the + * DLL VERSIONINFO structure. + * - PNG_USER_VERSIONINFO_COMMENTS + * - PNG_USER_VERSIONINFO_COMPANYNAME + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS + */ + +#ifdef __STDC__ +#ifdef SPECIALBUILD +# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") +#endif + +#ifdef PRIVATEBUILD +# pragma message("PRIVATEBUILD is deprecated.\ + Use PNG_USER_PRIVATEBUILD instead.") +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif +#endif /* __STDC__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble + Restored at libpng-1.2.21 */ +#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \ + !defined(PNG_WARN_UNINITIALIZED_ROW) +# define PNG_WARN_UNINITIALIZED_ROW 1 +#endif +/* End of material added at libpng-1.2.19/1.2.21 */ + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled in 1.2.41. */ +#ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +#else +# ifndef PNG_BENIGN_ERRORS_SUPPORTED +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* Added in libpng-1.2.41 */ +#if !defined(PNG_NO_WARNINGS) && !defined(PNG_WARNINGS_SUPPORTED) +# define PNG_WARNINGS_SUPPORTED +#endif + +#if !defined(PNG_NO_ERROR_TEXT) && !defined(PNG_ERROR_TEXT_SUPPORTED) +# define PNG_ERROR_TEXT_SUPPORTED +#endif + +#if !defined(PNG_NO_CHECK_cHRM) && !defined(PNG_CHECK_cHRM_SUPPORTED) +# define PNG_CHECK_cHRM_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + * support PNGs that are embedded in MNG datastreams + */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#ifdef __CYGWIN__ +# ifdef ALL_STATIC +# ifdef PNG_BUILD_DLL +# undef PNG_BUILD_DLL +# endif +# ifdef PNG_USE_DLL +# undef PNG_USE_DLL +# endif +# ifdef PNG_DLL +# undef PNG_DLL +# endif +# ifndef PNG_STATIC +# define PNG_STATIC +# endif +# else +# ifdef PNG_BUILD_DLL +# ifdef PNG_STATIC +# undef PNG_STATIC +# endif +# ifdef PNG_USE_DLL +# undef PNG_USE_DLL +# endif +# ifndef PNG_DLL +# define PNG_DLL +# endif +# else +# ifdef PNG_STATIC +# ifdef PNG_USE_DLL +# undef PNG_USE_DLL +# endif +# ifdef PNG_DLL +# undef PNG_DLL +# endif +# else +# ifndef PNG_USE_DLL +# define PNG_USE_DLL +# endif +# ifndef PNG_DLL +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#if !defined(PNG_NO_STDIO) && !defined(PNG_STDIO_SUPPORTED) +# define PNG_STDIO_SUPPORTED +#endif + +#ifdef _WIN32_WCE +# include + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO + /* abort() may not be supported on some/all Windows CE platforms */ +# define PNG_ABORT() exit(-1) +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include +# endif +# endif +# else +# ifndef _WIN32_WCE +/* "stdio.h" functions are not supported on WindowsCE */ +# include +# endif +# endif + +#if !(defined PNG_NO_CONSOLE_IO) && !defined(PNG_CONSOLE_IO_SUPPORTED) +# define PNG_CONSOLE_IO_SUPPORTED +#endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + * + * You can bypass this test if you know that your application uses exactly + * the same setjmp.h that was included when libpng was built. Only define + * PNG_SKIP_SETJMP_CHECK while building your application, prior to the + * application's '#include "png.h"'. Don't define PNG_SKIP_SETJMP_CHECK + * while building a separate libpng library for general use. + */ + +# ifndef PNG_SKIP_SETJMP_CHECK +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + /* If you encounter a compiler error here, see the explanation + * near the end of INSTALL. + */ + __pngconf.h__ in libpng already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ +# endif /* PNG_SKIP_SETJMP_CHECK */ + + /* include setjmp.h for error handling */ +# include + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include +#else +# include +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED +# ifdef MACOS + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +/* I have no idea why is this necessary... */ +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt support was added. iTXt support was turned off by default through + * libpng-1.2.x, to support old apps that malloc the png_text structure + * instead of calling png_set_text() and letting libpng malloc it. It + * will be turned on by default in libpng-1.4.0. + */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt +# define PNG_NO_READ_iTXt +# endif +# ifndef PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_iTXt +# endif +#endif + +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#ifdef PNG_READ_SUPPORTED + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +/* PNG_PROGRESSIVE_READ_NOT_SUPPORTED is deprecated. */ +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following define: */ +#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ + +/* PNG_NO_SEQUENTIAL_READ_SUPPORTED is deprecated. */ +#if !defined(PNG_NO_SEQUENTIAL_READ) && \ + !defined(PNG_SEQUENTIAL_READ_SUPPORTED) && \ + !defined(PNG_NO_SEQUENTIAL_READ_SUPPORTED) +# define PNG_SEQUENTIAL_READ_SUPPORTED +#endif + +#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#ifdef PNG_WRITE_SUPPORTED + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +#ifndef PNG_1_0_X +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +#endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ +#endif + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + !defined(PNG_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_1_0_X +# ifndef PNG_NO_ERROR_NUMBERS +# define PNG_ERROR_NUMBERS_SUPPORTED +# endif +#endif /* PNG_1_0_X */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + * and removed from version 1.2.20. The following will be removed + * from libpng-1.4.0 +*/ + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE) +# ifndef PNG_OPTIMIZED_CODE_SUPPORTED +# define PNG_OPTIMIZED_CODE_SUPPORTED +# endif +#endif + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif + +# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4) + /* work around 64-bit gcc compiler bugs in gcc-3.x */ +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# ifdef __APPLE__ +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh)) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_MMX_CODE_SUPPORTED +# endif + +#endif +/* end of obsolete code to be removed from libpng-1.4.0 */ + +/* Added at libpng-1.2.0 */ +#ifndef PNG_1_0_X +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#ifndef PNG_1_0_X +# ifndef PNG_SET_USER_LIMITS_SUPPORTED +# ifndef PNG_NO_SET_USER_LIMITS +# define PNG_SET_USER_LIMITS_SUPPORTED +# endif +# endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.0.53 and 1.2.43 */ +#ifndef PNG_USER_LIMITS_SUPPORTED +# ifndef PNG_NO_USER_LIMITS +# define PNG_USER_LIMITS_SUPPORTED +# endif +#endif + +/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter + * how large, set these limits to 0x7fffffffL + */ +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + +/* Added at libpng-1.2.43. To accept all valid PNGs no matter + * how large, set these two limits to 0. + */ +#ifndef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 0 +#endif + +/* Added at libpng-1.2.43 */ +#ifndef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 0 +#endif + +#ifndef PNG_LITERAL_SHARP +# define PNG_LITERAL_SHARP 0x23 +#endif +#ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET +# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b +#endif +#ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET +# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d +#endif + +/* Added at libpng-1.2.34 */ +#ifndef PNG_STRING_NEWLINE +#define PNG_STRING_NEWLINE "\n" +#endif + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +#if !defined(PNG_NO_POINTER_INDEXING) && \ + !defined(PNG_POINTER_INDEXING_SUPPORTED) +# define PNG_POINTER_INDEXING_SUPPORTED +#endif + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif + +#ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_NO_CONVERT_tIME +# ifndef _WIN32_WCE +/* The "tm" structure is not supported on WindowsCE */ +# ifndef PNG_CONVERT_tIME_SUPPORTED +# define PNG_CONVERT_tIME_SUPPORTED +# endif +# endif +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_FILTER) && !defined(PNG_WRITE_FILTER_SUPPORTED) +# define PNG_WRITE_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#endif /* PNG_WRITE_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* Need the time information for converting tIME chunks */ +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* "time.h" functions are not supported on WindowsCE */ +# include +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +#ifdef PNG_SIZE_T + typedef PNG_SIZE_T png_size_t; +# define png_sizeof(x) png_convert_size(sizeof(x)) +#else + typedef size_t png_size_t; +# define png_sizeof(x) sizeof(x) +#endif + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#ifdef FAR +# ifdef M_I86MM +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#ifdef _WIN32_WCE +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.4.0 - GR-P */ +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#ifdef __CYGWIN__ +# ifndef PNG_STATIC +# ifdef PNG_USE_GLOBAL_ARRAYS +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# ifndef PNG_USE_LOCAL_ARRAYS +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# ifdef PNG_USE_GLOBAL_ARRAYS +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || \ + (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#ifdef __CYGWIN__ +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# ifndef PNGAPI +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# ifndef PNG_IMPEXP + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# ifdef PNG_BUILD_DLL +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# ifndef PNG_IMPEXP +# ifdef PNG_BUILD_DLL +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# ifndef PNGAPI +# define PNGAPI _System +# endif +# else +# if 0 /* ... other platforms, with other meanings */ +# endif +# endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. + */ +# ifdef __GNUC__ +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif + + /* This specifically protects structure members that should only be + * accessed from within the library, therefore should be empty during + * a library build. + */ +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_DEPSTRUCT +# define PNG_DEPSTRUCT __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif /* PNG_PRIVATE */ +# endif /* __GNUC__ */ +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_DEPSTRUCT +# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#ifdef USE_FAR_KEYWORD /* memory model independent fns */ +/* Use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_snprintf _fsnprintf /* Added to v 1.2.19 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* Use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# ifndef PNG_NO_SNPRINTF +# ifdef _MSC_VER +# define png_snprintf _snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 _snprintf +# define png_snprintf6 _snprintf +# else +# define png_snprintf snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 snprintf +# define png_snprintf6 snprintf +# endif +# else + /* You don't have or don't want to use snprintf(). Caution: Using + * sprintf instead of snprintf exposes your application to accidental + * or malevolent buffer overflows. If you don't have snprintf() + * as a general rule you should provide one (you can get one from + * Portable OpenSSH). + */ +# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +# endif +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGCONF_H */ diff --git a/src/Menge/include/splinelib/CatmullRom.h b/src/Menge/include/splinelib/CatmullRom.h new file mode 100644 index 00000000..f1acb64c --- /dev/null +++ b/src/Menge/include/splinelib/CatmullRom.h @@ -0,0 +1,123 @@ +/* ----------------------------------------------------------------------------- +splinelib - Spline library +Copyright (C) 2010 Sean Curtis + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +------------------------------------------------------------------------------*/ + +#ifndef __CATMULLROM_H__ +#define __CATMULLROM_H__ + +#include "Hermite.h" +#include + +namespace Spline { + + // Class for an arbitrary-dimensioned hermite curve mapping from real -> R^T + template + class CatmullRomCurve : public HermiteCurve< Vector > { + public: + CatmullRomCurve():HermiteCurve() {} + + // add a point to the curve + void addPoint( float t, const Vector & value ); + void addPoint( float t, const Vector & value, const Vector & tangent ); + + int insertPoint( float t, const Vector & value ); + int insertPoint( float t, const Vector & value, const Vector & tangent ); + + // Creates the tangents for the curve + void createTangents( bool periodic=false ); + + }; + + typedef CatmullRomCurve< float > CatmullRom1D; + + /////////////////////////////////////////////////////////////////////////// + + template + void CatmullRomCurve::addPoint( float t, const Vector & value ) { + // NOTE: THIS IS AMAZING! + // When instantiating with CatmullRomCurve, Vector() + // creates a float initialzied to zero. + HermiteCurve::addPoint( t, value, Vector() ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + void CatmullRomCurve::addPoint( float t, const Vector & value, const Vector & tangent ) { + HermiteCurve::addPoint( t, value, tangent ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + int CatmullRomCurve::insertPoint( float t, const Vector & value ) { + // NOTE: THIS IS AMAZING! + // When instantiating with CatmullRomCurve, Vector() + // creates a float initialzied to zero. + return HermiteCurve::insertPoint( t, value, Vector() ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + int CatmullRomCurve::insertPoint( float t, const Vector & value, const Vector & tangent ) { + return HermiteCurve::insertPoint( t, value, tangent ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + void CatmullRomCurve::createTangents( bool periodic ) { + assert( this->_cvCount > 1 && "Can't create tangents for catmullrom curve with less than 2 keys" ); + + if ( periodic ) { + assert( this->_cvCount >= 3 && "Can't perform periodic without at least three keys" ); + int last = this->_cvCount - 1; + + // initial tangent + this->_cvs[0]._tangent = (this->_cvs[1]._value - this->_cvs[last - 1]._value ) / ( this->_cvs[1]._t - this->_cvs[0]._t + this->_cvs[last]._t - this->_cvs[last-1]._t ); + + // internal tangets + for ( int i = 1; i < last; ++i ) { + float a = this->_cvs[i-1]._t; + float b = this->_cvs[i+1]._t; + this->_cvs[i]._tangent = (this->_cvs[i+1]._value - this->_cvs[i-1]._value ) / ( b - a ); + } + + // final tangent + this->_cvs[last]._tangent = this->_cvs[0]._tangent; + } else { + int last = this->_cvCount - 1; + + // initial tangent + this->_cvs[0]._tangent = (this->_cvs[1]._value - this->_cvs[0]._value ) / ( this->_cvs[1]._t - this->_cvs[0]._t ); + + // internal tangets + for ( int i = 1; i < last; ++i ) { + float a = this->_cvs[i-1]._t; + float b = this->_cvs[i+1]._t; + this->_cvs[i]._tangent = (this->_cvs[i+1]._value - this->_cvs[i-1]._value ) / ( b - a ); + } + + // final tangent + this->_cvs[last]._tangent = (this->_cvs[last]._value - this->_cvs[last-1]._value ) / ( this->_cvs[last]._t - this->_cvs[last-1]._t ); + } + } +} + +#endif // __CATMULLROM_H__ diff --git a/src/Menge/include/splinelib/Hermite.h b/src/Menge/include/splinelib/Hermite.h new file mode 100644 index 00000000..4e244f72 --- /dev/null +++ b/src/Menge/include/splinelib/Hermite.h @@ -0,0 +1,648 @@ +/* ----------------------------------------------------------------------------- +splinelib - Spline library +Copyright (C) 2010 Sean Curtis + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +------------------------------------------------------------------------------*/ + +#ifndef __HERMITE_H__ +#define __HERMITE_H__ + +#include "HermitePoint.h" +#include +#include + +// If this is set to zero: the curve won't be printed. +// Any postive integer will compute the printed hermite at +// CURVE_SAMPLES number of uniformly distributed values over the +// domain of the hermite +#define CURVE_SAMPLES 0 + +namespace Spline { + + // Class for an arbitrary-dimensioned hermite curve mapping from real -> R^T + template + class HermiteCurve { + public: + HermiteCurve():_cvCount(0), _cvs(0x0) {} + ~HermiteCurve(); + + HermiteCurve & operator=( HermiteCurve & crv ); + + // Evaluates the curve at parameter value t + Vector evaluate( float t ) const; + + // Evaluates the tangent of the curve at parameter value t + Vector evalTangent( float t ) const; + + // Evaluates the curve linearly between points + Vector evaluateLinear( float t ) const; + + // Solves the inverse, given the interpolated value, determines what value will find it + // The paramter value is put in the provided argument param + // the function returns boolean if it was able to find such a value, + // if it returns false, the param value is undetermined and meaningless + // THIS ALGORITHM ASSUMES a 1-to-1 function. More particularly, a monotonically increasing + // function. It uses bijection. Otherwise the inverse for the cubic function + // is ill-defined. + bool inverse( const Vector & value, float & param, float threshold = 0.0001f ) const; + + // Returns the smallest parameter for which this curve is defined + float minT() const; + + // Returns the largets parameter for which this curve is defined + float maxT() const; + + // add a point to the curve + void addPoint( float t, const Vector & value, const Vector & tangent ); + + // insert a point into the curve + // returns the index of the insertion + int insertPoint( float t, const Vector & value, const Vector & tangent ); + + // clear the vector + void clear(); + + // Number of keys + inline int keyCount() const { return _cvCount; } + + // return the param of a key + inline float keyParam( int index ) const { return _cvs[ index]._t; } + + // Set the value of a key + inline void setKeyParam( int index, float t ) { _cvs[index]._t = t; } + + // Return the value of a key + inline Vector keyValue( int index ) const { return _cvs[ index ]._value; } + + // Set the value of a key + inline void setKeyValue( int index, Vector value ) { _cvs[index]._value = value; } + + // offsets the value of a key + inline void offsetKeyParam( int index, Vector value ) { _cvs[index]._t += value; } + + // offsets the value of a key + inline void offsetKeyValue( int index, Vector value ) { _cvs[index]._value += value; } + + // offsets the value of a key + inline void offsetKeyTangent( int index, Vector value ) { _cvs[index]._tangent += value; } + + // scales the tangent by the given value + inline void scaleKeyTangent( int index, float scale ) { _cvs[index]._tangent *= scale; } + + // set the tangent of a key + inline void setKeyTangent( int index, Vector tan ) { _cvs[index]._tangent = tan; } + + // Return the tangent of a key + inline Vector keyTangent( int index ) { return _cvs[ index ]._tangent; } + + // Sets the value and tangent of a key + inline void setKeyValTan( int index, Vector val, Vector tan ) { _cvs[index]._value = val; _cvs[index]._tangent = tan; } + + // Calc tangent for the given index based on surrounding values + void calcTangent( int index, bool periodic=false ); + + // Calculate a 2nd-order tangent for non-uniform key distribution + void calcTangent2( int index, bool periodic=false ); + + // finding keys + // searches for the index of the key with the paramter closest to t + int findClosestIndex( float t ) const; + // searches for the param value closest to the provided parameter t + float findClosestParam( float t ) const; + + // functions for removing keys - they report true if a key was removed + // remove key based on param value + bool removeParam( float t ); + // remove the ith key + bool removeKey( int i ); + + // Compute new position value + // Given the pair (t, val) provides a value that will cause the function to evaluate val at t. + // The value is what the p value at the START of the applicable interval should be. + Vector valueConstraint0( float t, Vector val ); + // This does the same, except solving for P_1 (instead of P_0) + Vector valueConstraint1( float t, Vector val ); + + // These functions, like valueConstraint*, compute a value with given constraints + // In this case, it computes a TANGENT based on four constraints: + // the values of each key defining the interval + // the tangent of the other end of the interval + // and a value on the interior of the interval + // the "other end" is defined by which function is called + // the 0/1 in the function name indicates that this key is the + // start/end of the interval, respectively + //void setConstrainedTangent0( int key, float constrainT, const Vector & constrainV ); + void setConstrainedTangent1( int key, float constrainT, const Vector & constrainV ); + + template friend std::ostream & operator << ( std::ostream & out, const HermiteCurve & v ); + + //protected: + // Evaluate the curve for a given value of t, having already determined that + // the paramter t is in the interval defined by the ith and i+1st keys + Vector _evalInterval( int i, float t ) const; + // Evaluate the curve for a given value of t, having already determined that + // the parameter t is in the interval defined by the ith and i+1st keys + Vector _evalTanInternal( int i, float t ) const; + // Number of cvs in this curve + int _cvCount; + HermitePoint< Vector > * _cvs; + }; + + typedef HermiteCurve< float > Hermite1D; + + /////////////////////////////////////////////////////////////////////////// + + template + HermiteCurve::~HermiteCurve() { + if ( _cvs ) delete [] _cvs; + } + + /////////////////////////////////////////////////////////////////////////// + + template + HermiteCurve & HermiteCurve::operator=( HermiteCurve & crv ) { + if ( this != &crv ) { + if ( _cvCount != crv._cvCount ) { + _cvCount = crv._cvCount; + delete [] _cvs; + _cvs = new HermitePoint< Vector >[ _cvCount ]; + } + for ( int i = 0; i < _cvCount; ++i ) { + _cvs[i] = crv._cvs[i]; + } + } + return *this; + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::_evalInterval( int i, float t ) const { + float a = _cvs[i]._t; + float b = _cvs[i+1]._t; + float h = b - a; + t = ( t - a ) / h; + float t2 = t * t; + float t3 = t2 * t; + return _cvs[i].evaluateAsFirst( t3, t2, t, h ) + _cvs[i+1].evaluateAsSecond( t3, t2, t, h ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::_evalTanInternal( int i, float t ) const { + float a = _cvs[i]._t; + float b = _cvs[i+1]._t; + float h = b - a; + t = ( t - a ) / h; + float t2 = t * t; + return ( _cvs[i].evalTanAsFirst( t2, t, h ) + _cvs[i+1].evalTanAsSecond( t2, t, h ) ) / h; + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::evaluate( float t ) const { + assert( _cvCount > 0 && "Calling evaluate without any points causes an error" ); + + int last = _cvCount - 1; + // Check if the value is beyond the extents of the curve + // TODO: This assumes constant value beyond the boundaries + // OPTIONALLY, allow other extrapolation methods (such as perioid, linear, etc.) + if ( t <= _cvs[0]._t) { + return _cvs[0]._value; + } else if ( t >= _cvs[ last ]._t ) { + return _cvs[ last ]._value; + } + + // Determine the interval overwhich to evaluate t + int i = 1; + while ( i < last && _cvs[ i ]._t < t ) ++i; + --i; + return _evalInterval( i, t ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::evalTangent( float t ) const { + assert( _cvCount > 0 && "Calling evaluate without any points causes an error" ); + + int last = _cvCount - 1; + // Check if the value is beyond the extents of the curve + // TODO: This assumes constant value beyond the boundaries + // OPTIONALLY, allow other extrapolation methods (such as perioid, linear, etc.) + if ( t <= _cvs[0]._t) { + return Vector();//_cvs[0]._tangent; + } else if ( t >= _cvs[ last ]._t ) { + return Vector();//_cvs[ last ]._tangent; + } + + // Determine the interval overwhich to evaluate t + int i = 1; + while ( i < last && _cvs[ i ]._t < t ) ++i; + --i; + return _evalTanInternal( i, t ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::evaluateLinear( float t ) const { + assert( _cvCount > 0 && "Calling evaluate without any points causes an error" ); + + int last = _cvCount - 1; + // Check if the value is beyond the extents of the curve + // TODO: This assumes constant value beyond the boundaries + // OPTIONALLY, allow other extrapolation methods (such as perioid, linear, etc.) + if ( t <= _cvs[0]._t) { + return _cvs[0]._value; + } else if ( t >= _cvs[ last ]._t ) { + return _cvs[ last ]._value; + } + + // Determine the interval overwhich to evaluate t + int i = 1; + while ( i < last && _cvs[ i ]._t < t ) ++i; + --i; + + // compute the interval parameters + float a = _cvs[i]._t; + float b = _cvs[i+1]._t; + float h = b - a; + t = ( t - a ) / h; + return (1-t) * _cvs[i]._value + t * _cvs[i+1]._value; + } + + /////////////////////////////////////////////////////////////////////////// + + template + void HermiteCurve::addPoint( float t, const Vector & value, const Vector & tangent ) { + ++_cvCount; + HermitePoint< Vector > * newCvs = new HermitePoint< Vector >[ _cvCount ]; + if ( _cvCount > 1 ) { + memcpy( newCvs, _cvs, (_cvCount - 1) * sizeof( HermitePoint ) ); + delete [] _cvs; + } + newCvs[ _cvCount - 1 ] = HermitePoint( t, value, tangent ); + _cvs = newCvs; + } + + /////////////////////////////////////////////////////////////////////////// + + template + int HermiteCurve::insertPoint( float t, const Vector & value, const Vector & tangent ) { + // assume it's already sorted + ++_cvCount; + HermitePoint< Vector > * newCvs = new HermitePoint< Vector >[ _cvCount ]; + int d = 0; + int s = 0; + int insertIdx = -1; + while ( d < _cvCount ) { + if ( s < _cvCount - 1 && ( _cvs[s]._t < t || insertIdx != -1 ) ) { + newCvs[ d ] = _cvs[s]; + ++s; + } else { + newCvs[ d ] = HermitePoint< Vector >( t, value, tangent ); + insertIdx = d; + } + ++d; + } + delete [] _cvs; + _cvs = newCvs; + + return insertIdx; + } + + /////////////////////////////////////////////////////////////////////////// + + template + float HermiteCurve::minT() const { + assert( _cvCount > 0 && "Calling minT without any points causes an error" ); + return _cvs[0]._t; + } + + /////////////////////////////////////////////////////////////////////////// + + template + float HermiteCurve::maxT() const { + assert( _cvCount > 0 && "Calling maxT without any points causes an error" ); + return _cvs[ _cvCount - 1 ]._t; + } + + /////////////////////////////////////////////////////////////////////////// + + template + void HermiteCurve::clear() { + if ( _cvs ) { + _cvCount = 0; + delete [] _cvs; + _cvs = 0x0; + } + } + + /////////////////////////////////////////////////////////////////////////// + + template + std::ostream & operator << ( std::ostream & out, const HermiteCurve & curve ) { + out << curve._cvCount << "\n"; + for ( int i = 0; i < curve._cvCount; ++i ) { + out << curve._cvs[i]._t << " " << curve._cvs[i]._value << " " << curve._cvs[i]._tangent << "\n"; + } + //std::cout << "Hermite:"; + //for ( int i = 0; i < curve._cvCount; ++i ) { + // std::cout << "\n\t" << curve._cvs[i]; + //} +#if CURVE_SAMPLES + float dt = (curve._cvs[ curve._cvCount - 1]._t - curve._cvs[0]._t) / (float)CURVE_SAMPLES; + for ( int i = 0; i <= CURVE_SAMPLES; ++i ) { + std::cout << "\n" << (i * dt ) << " " << curve.evaluate( i * dt ); + } +#endif + return out; + } + + /////////////////////////////////////////////////////////////////////////// + + template + void HermiteCurve::calcTangent( int i, bool periodic ) { + int prev, next; + float h; + int last = (int)_cvCount - 1; + if ( i == 0 || i == last) { // first + if ( periodic ) { + prev = last - 1; + next = 1; + h = _cvs[1]._t - _cvs[0]._t + _cvs[last]._t - _cvs[last-1]._t; + } else { + if ( i == 0 ) { + _cvs[0]._tangent = (_cvs[1]._value - _cvs[0]._value ) / ( _cvs[1]._t - _cvs[0]._t ); + } else { + _cvs[last]._tangent = (_cvs[last]._value - _cvs[last-1]._value ) / ( _cvs[last]._t - _cvs[last-1]._t ); + } + return; + } + } else { // middle + prev = i - 1; + next = i + 1; + h = _cvs[next]._t - _cvs[prev]._t; + } + _cvs[i]._tangent = (_cvs[next]._value - _cvs[prev]._value ) / h; + } + + /////////////////////////////////////////////////////////////////////////// + + template + void HermiteCurve::calcTangent2( int i, bool periodic ) { + float h0, h1; + float f0, f2; + int last = (int)_cvCount - 1; + if ( i == 0 || i == last) { // first + if ( periodic ) { + f0 = _cvs[ last - 1 ]._value; + f2 = _cvs[ 1 ]._value; + h0 = _cvs[0]._t - _cvs[1]._t; // note, this LOOKS backwards but matches the taylor expansion + h1 = _cvs[last]._t - _cvs[last-1]._t; + } else { + // if not periodic and on the boundary, simply do the forward/backward difference + if ( i == 0 ) { + _cvs[0]._tangent = (_cvs[1]._value - _cvs[0]._value ) / ( _cvs[1]._t - _cvs[0]._t ); + } else { + _cvs[last]._tangent = (_cvs[last]._value - _cvs[last-1]._value ) / ( _cvs[last]._t - _cvs[last-1]._t ); + } + return; + } + } else { // middle + f0 = _cvs[ i - 1 ]._value; + f2 = _cvs[ i + 1 ]._value; + h0 = _cvs[ i - 1 ]._t - _cvs[ i ]._t; // note, this LOOKS backwards but matches the taylor expansion + h1 = _cvs[ i + 1 ]._t - _cvs[ i ]._t; + } + float f1 = _cvs[i]._value; + float h12 = h1 * h1; + float h02 = h0 * h0; + _cvs[i]._tangent = -(h02 * (f2 - f1) + h12 * (f1 - f0) ) / ( h1 * h0 * ( h1 - h0 ) ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + int HermiteCurve::findClosestIndex( float t ) const { + int count = (int)_cvCount; + int closest = 0; + float dist = fabs( _cvs[0]._t - t ); + for ( int i = 1; i < count; ++i ) { + float d = fabs( _cvs[i]._t - t ); + if ( d < dist ) { + dist = d; + closest = i; + } + } + return closest; + } + + /////////////////////////////////////////////////////////////////////////// + + template + float HermiteCurve::findClosestParam( float t ) const { + int count = (int)_cvCount; + float closest = _cvs[0]._t; + float dist = fabs( _cvs[0]._t - t ); + for ( int i = 1; i < count; ++i ) { + float d = fabs( _cvs[i]._t - t ); + if ( d < dist ) { + dist = d; + closest = _cvs[i]._t; + } + } + return closest; + } + + /////////////////////////////////////////////////////////////////////////// + + template + bool HermiteCurve::inverse( const Vector & value, float & param, float threshold ) const { + // GIven that this assumes monotonically increasing values, I can target this a bit better + // First, determine what interval the value is in + assert( _cvCount > 0 && "Calling evaluate without any points causes an error" ); + + int last = _cvCount - 1; + // Check if the value is beyond the extents of the curve + // TODO: This assumes constant value beyond the boundaries + // OPTIONALLY, allow other extrapolation methods (such as perioid, linear, etc.) + if ( value < _cvs[0]._value ) { + return false; + } else if ( value > _cvs[ last ]._value ) { + return false; + } + + // Determine the interval overwhich to evaluate t + int i = 1; + while ( i < last && _cvs[ i ]._value < value ) ++i; + --i; + + float low, high; + low = _cvs[i]._t; + high = _cvs[i+1]._t; + param = ( low + high ) * 0.5f; + Vector testVal = _evalInterval( i, param ); + while ( (high - low) > threshold && abs( testVal - value ) > threshold ) { + if ( testVal > value ) { + high = param; + param = ( low + high ) * 0.5f; + testVal = _evalInterval( i, param ); + } else { + low = param; + param = ( low + high ) * 0.5f; + testVal = _evalInterval( i, param ); + } + } + + return abs( testVal - value ) > threshold; + } + + /////////////////////////////////////////////////////////////////////////// + + template + bool HermiteCurve::removeParam( float t ) { + assert( _cvCount > 0 && "Trying to remove key from empty curve" ); + int key = -1; + for ( int i = 0; i < _cvCount; ++i ) { + if ( _cvs[i]._t == t ) { + key = i; + break; + } + } + if ( key != -1 ) { + return removeKey( key ); + } + + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + template + bool HermiteCurve::removeKey( int i ) { + assert( i >= 0 && i < _cvCount && "Trying to remove a key which doesn't exist" ); + + int newCount = _cvCount - 1; + HermitePoint< Vector > * newCvs = new HermitePoint< Vector >[ newCount ]; + int s = 0, d = 0; + while ( d < newCount) { + if ( s != i ) { + newCvs[ d ] = _cvs[ s ]; + ++d; + } + ++s; + } + delete [] _cvs; + _cvs = newCvs; + _cvCount = newCount; + + return false; + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::valueConstraint0( float t, Vector val ) { + int last = _cvCount - 1; + // identify the interval + // if I'm outside the domain of the curve, then I should set the end point to be val + if ( t <= _cvs[0]._t || t >= _cvs[ last ]._t ) { + return val; + } + + // Determine the interval overwhich to evaluate t + int i = 0; + while ( i < last && _cvs[ i ]._t < t ) ++i; + --i; + + // compute the interval parameters + float a = _cvs[i]._t; + float b = _cvs[i+1]._t; + float h = b - a; + t = ( t - a ) / h; + // compute normalized t + + float t2 = t * t; + float t3 = t2 * t; + float right = _cvs[i+1].evaluateAsSecond( t3, t2, t, h ); + float h1 = 2 * t3 - 3 * t2 + 1; + float h3 = t3 - 2 * t2 + t; + float tgtVal = ( val - right - _cvs[i]._tangent * ( h3 * h ) ) / h1; + + return tgtVal; + } + + /////////////////////////////////////////////////////////////////////////// + + template + Vector HermiteCurve::valueConstraint1( float t, Vector val ) { + int last = _cvCount - 1; + // identify the interval + // if I'm outside the domain of the curve, then I should set the end point to be val + if ( t <= _cvs[0]._t || t >= _cvs[ last ]._t ) { + return val; + } + + // Determine the interval overwhich to evaluate t + int i = 0; + while ( i < last && _cvs[ i ]._t < t ) ++i; + --i; + + // compute the interval parameters + float a = _cvs[i]._t; + float b = _cvs[i+1]._t; + float h = b - a; + t = ( t - a ) / h; + // compute normalized t + + float t2 = t * t; + float t3 = t2 * t; + float left = _cvs[i].evaluateAsFirst( t3, t2, t, h ); + float h2 = -2 * t3 + 3 * t2; + float h4 = t3 - t2; + float tgtVal = ( val - left - _cvs[i+1]._tangent * h4 * h ) / h2; + + return tgtVal; + } + + /////////////////////////////////////////////////////////////////////////// + + template + void HermiteCurve::setConstrainedTangent1( int key, float constrainT, const Vector & constrainV ) { + assert( key > 0 && "Can't use the constraint with 0 as an ending key" ); + assert( key < _cvCount && "Invalid key" ); + + // compute the interval parameters + // compute normalized t + float a = _cvs[key-1]._t; + float b = _cvs[key]._t; + float h = b - a; + float t = ( constrainT - a ) / h; + + float t2 = t * t; + float t3 = t2 * t; + float left = _cvs[ key - 1 ].evaluateAsFirst( t3, t2, t, h ); + float h2 = ( 3 * t2 - 2 * t3 ) * _cvs[ key ]._value; + float h3 = t3 - t2; + _cvs[ key ]._tangent = ( constrainV - left - h2 ) / ( h3 * h ); + } +} + +#endif // __HERMITE_H__ diff --git a/src/Menge/include/splinelib/HermitePoint.h b/src/Menge/include/splinelib/HermitePoint.h new file mode 100644 index 00000000..e7f8a081 --- /dev/null +++ b/src/Menge/include/splinelib/HermitePoint.h @@ -0,0 +1,136 @@ +/* ----------------------------------------------------------------------------- +splinelib - Spline library +Copyright (C) 2010 Sean Curtis + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +------------------------------------------------------------------------------*/ + +#ifndef __HERMITEPOINT_H__ +#define __HERMITEPOINT_H__ + +#include +#include + +namespace Spline { + + // A class for 1-dimensional hermite curves. I.e. the function maps real -> real + template + class HermitePoint { + public: + HermitePoint(): _t(0.f), _value(DataVector()), _tangent(DataVector()){} + HermitePoint( float t, const DataVector & val, const DataVector & tan ): _t(t), _value(val), _tangent(tan) {} + + HermitePoint & operator=( const HermitePoint & pt ); + + bool operator==( const HermitePoint & pt ); + + // Evaluate the portion of the hermite function which uses this point + // as the FIRST point in the curve + DataVector evaluateAsFirst( float s3, float s2, float s, float scale=1.f ) const; + + // Evaluate the portion of the hermite function which uses this point + // as the SECOND point in the curve + DataVector evaluateAsSecond( float s3, float s2, float s, float scale=1.f ) const; + + // Evaluate the tangent in the portion of the hermite function which uses this point + // as the FIRST point in the curve + DataVector evalTanAsFirst( float s2, float s, float scale=1.f ) const; + + // Evaluate the tangent in the portion of the hermite function which uses this point + // as the SECOND point in the curve + DataVector evalTanAsSecond( float s2, float s, float scale=1.f ) const; + + // Stream the Hermite Point to the stream + template friend std::ostream & operator << ( std::ostream & out, const HermitePoint & v ); + + // Allow hermite points to be sorted based on parameter + template friend bool pointCompare( const HermitePoint & v1, const HermitePoint & v2 ); + + float _t; + DataVector _value; + DataVector _tangent; + }; + + /////////////////////////////////////////////////////////////////////////// + + template + bool HermitePoint::operator==( const HermitePoint & pt ) { + // this threshold only works for floats + return fabs(_t - pt._t) < 1e-5 && fabs(_value - pt._value) < 1e-5 && fabs(_tangent - pt._tangent ) < 1e-5; + } + + /////////////////////////////////////////////////////////////////////////// + + template + HermitePoint & HermitePoint::operator=( const HermitePoint & pt ) { + _t = pt._t; + _value = pt._value; + _tangent = pt._tangent; + return *this; + } + + /////////////////////////////////////////////////////////////////////////// + + template + DataVector HermitePoint::evaluateAsFirst( float s3, float s2, float s, float scale ) const { + float h1 = 2 * s3 - 3 * s2 + 1; + float h3 = s3 - 2 * s2 + s; + return _value * h1 + _tangent * ( h3 * scale ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + DataVector HermitePoint::evaluateAsSecond( float s3, float s2, float s, float scale ) const { + float h2 = -2 * s3 + 3 * s2; + float h4 = s3 - s2; + return _value * h2 + _tangent * ( h4 * scale ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + DataVector HermitePoint::evalTanAsFirst( float s2, float s, float scale ) const { + float h1 = 6 * s2 - 6 * s; + float h3 = 3 * s2 - 4 * s + 1; + return _value * h1 + _tangent * ( h3 * scale ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + DataVector HermitePoint::evalTanAsSecond( float s2, float s, float scale ) const { + float h2 = -6 * s2 + 6 * s; + float h4 = 3 * s2 - 2 * s; + return _value * h2 + _tangent * ( h4 * scale ); + } + + /////////////////////////////////////////////////////////////////////////// + + template + std::ostream & operator << ( std::ostream & out, const HermitePoint & v ) { + std::cout << "t(" << v._t << "), val(" << v._value << "), tan(" << v._tangent << ")"; + return out; + } + + /////////////////////////////////////////////////////////////////////////// + + template + bool pointCompare( const HermitePoint & v1, const HermitePoint & v2 ) { + return v1._t < v2._t; + } +} + +#endif // __HERMITEPOINT_H__ diff --git a/src/Menge/include/tclap/Arg.h b/src/Menge/include/tclap/Arg.h new file mode 100644 index 00000000..b28eef11 --- /dev/null +++ b/src/Menge/include/tclap/Arg.h @@ -0,0 +1,692 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: Arg.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_ARGUMENT_H +#define TCLAP_ARGUMENT_H + +#ifdef HAVE_CONFIG_H +#include +#else +#define HAVE_SSTREAM +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_SSTREAM) +#include +typedef std::istringstream istringstream; +#elif defined(HAVE_STRSTREAM) +#include +typedef std::istrstream istringstream; +#else +#error "Need a stringstream (sstream or strstream) to compile!" +#endif + +#include +#include +#include +#include +#include + +namespace TCLAP { + +/** + * A virtual base class that defines the essential data for all arguments. + * This class, or one of its existing children, must be subclassed to do + * anything. + */ +class Arg +{ + private: + /** + * Prevent accidental copying. + */ + Arg(const Arg& rhs); + + /** + * Prevent accidental copying. + */ + Arg& operator=(const Arg& rhs); + + /** + * Indicates whether the rest of the arguments should be ignored. + */ + static bool& ignoreRestRef() { static bool ign = false; return ign; } + + /** + * The delimiter that separates an argument flag/name from the + * value. + */ + static char& delimiterRef() { static char delim = ' '; return delim; } + + protected: + + /** + * The single char flag used to identify the argument. + * This value (preceded by a dash {-}), can be used to identify + * an argument on the command line. The _flag can be blank, + * in fact this is how unlabeled args work. Unlabeled args must + * override appropriate functions to get correct handling. Note + * that the _flag does NOT include the dash as part of the flag. + */ + std::string _flag; + + /** + * A single work namd indentifying the argument. + * This value (preceded by two dashed {--}) can also be used + * to identify an argument on the command line. Note that the + * _name does NOT include the two dashes as part of the _name. The + * _name cannot be blank. + */ + std::string _name; + + /** + * Description of the argument. + */ + std::string _description; + + /** + * Indicating whether the argument is required. + */ + bool _required; + + /** + * Label to be used in usage description. Normally set to + * "required", but can be changed when necessary. + */ + std::string _requireLabel; + + /** + * Indicates whether a value is required for the argument. + * Note that the value may be required but the argument/value + * combination may not be, as specified by _required. + */ + bool _valueRequired; + + /** + * Indicates whether the argument has been set. + * Indicates that a value on the command line has matched the + * name/flag of this argument and the values have been set accordingly. + */ + bool _alreadySet; + + /** + * A pointer to a vistitor object. + * The visitor allows special handling to occur as soon as the + * argument is matched. This defaults to NULL and should not + * be used unless absolutely necessary. + */ + Visitor* _visitor; + + /** + * Whether this argument can be ignored, if desired. + */ + bool _ignoreable; + + /** + * Indicates that the arg was set as part of an XOR and not on the + * command line. + */ + bool _xorSet; + + bool _acceptsMultipleValues; + + /** + * Performs the special handling described by the Vistitor. + */ + void _checkWithVisitor() const; + + /** + * Primary constructor. YOU (yes you) should NEVER construct an Arg + * directly, this is a base class that is extended by various children + * that are meant to be used. Use SwitchArg, ValueArg, MultiArg, + * UnlabeledValueArg, or UnlabeledMultiArg instead. + * + * \param flag - The flag identifying the argument. + * \param name - The name identifying the argument. + * \param desc - The description of the argument, used in the usage. + * \param req - Whether the argument is required. + * \param valreq - Whether the a value is required for the argument. + * \param v - The visitor checked by the argument. Defaults to NULL. + */ + Arg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + bool valreq, + Visitor* v = NULL ); + + public: + /** + * Destructor. + */ + virtual ~Arg(); + + /** + * Adds this to the specified list of Args. + * \param argList - The list to add this to. + */ + virtual void addToList( std::list& argList ) const; + + /** + * Begin ignoring arguments since the "--" argument was specified. + */ + static void beginIgnoring() { ignoreRestRef() = true; } + + /** + * Whether to ignore the rest. + */ + static bool ignoreRest() { return ignoreRestRef(); } + + /** + * The delimiter that separates an argument flag/name from the + * value. + */ + static char delimiter() { return delimiterRef(); } + + /** + * The char used as a place holder when SwitchArgs are combined. + * Currently set to the bell char (ASCII 7). + */ + static char blankChar() { return (char)7; } + + /** + * The char that indicates the beginning of a flag. Defaults to '-', but + * clients can define TCLAP_FLAGSTARTCHAR to override. + */ +#ifndef TCLAP_FLAGSTARTCHAR +#define TCLAP_FLAGSTARTCHAR '-' +#endif + static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; } + + /** + * The sting that indicates the beginning of a flag. Defaults to "-", but + * clients can define TCLAP_FLAGSTARTSTRING to override. Should be the same + * as TCLAP_FLAGSTARTCHAR. + */ +#ifndef TCLAP_FLAGSTARTSTRING +#define TCLAP_FLAGSTARTSTRING "-" +#endif + static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; } + + /** + * The sting that indicates the beginning of a name. Defaults to "--", but + * clients can define TCLAP_NAMESTARTSTRING to override. + */ +#ifndef TCLAP_NAMESTARTSTRING +#define TCLAP_NAMESTARTSTRING "--" +#endif + static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; } + + /** + * The name used to identify the ignore rest argument. + */ + static const std::string ignoreNameString() { return "ignore_rest"; } + + /** + * Sets the delimiter for all arguments. + * \param c - The character that delimits flags/names from values. + */ + static void setDelimiter( char c ) { delimiterRef() = c; } + + /** + * Pure virtual method meant to handle the parsing and value assignment + * of the string on the command line. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. What is + * passed in from main. + */ + virtual bool processArg(int *i, std::vector& args) = 0; + + /** + * Operator ==. + * Equality operator. Must be virtual to handle unlabeled args. + * \param a - The Arg to be compared to this. + */ + virtual bool operator==(const Arg& a) const; + + /** + * Returns the argument flag. + */ + const std::string& getFlag() const; + + /** + * Returns the argument name. + */ + const std::string& getName() const; + + /** + * Returns the argument description. + */ + std::string getDescription() const; + + /** + * Indicates whether the argument is required. + */ + virtual bool isRequired() const; + + /** + * Sets _required to true. This is used by the XorHandler. + * You really have no reason to ever use it. + */ + void forceRequired(); + + /** + * Sets the _alreadySet value to true. This is used by the XorHandler. + * You really have no reason to ever use it. + */ + void xorSet(); + + /** + * Indicates whether a value must be specified for argument. + */ + bool isValueRequired() const; + + /** + * Indicates whether the argument has already been set. Only true + * if the arg has been matched on the command line. + */ + bool isSet() const; + + /** + * Indicates whether the argument can be ignored, if desired. + */ + bool isIgnoreable() const; + + /** + * A method that tests whether a string matches this argument. + * This is generally called by the processArg() method. This + * method could be re-implemented by a child to change how + * arguments are specified on the command line. + * \param s - The string to be compared to the flag/name to determine + * whether the arg matches. + */ + virtual bool argMatches( const std::string& s ) const; + + /** + * Returns a simple string representation of the argument. + * Primarily for debugging. + */ + virtual std::string toString() const; + + /** + * Returns a short ID for the usage. + * \param valueId - The value used in the id. + */ + virtual std::string shortID( const std::string& valueId = "val" ) const; + + /** + * Returns a long ID for the usage. + * \param valueId - The value used in the id. + */ + virtual std::string longID( const std::string& valueId = "val" ) const; + + /** + * Trims a value off of the flag. + * \param flag - The string from which the flag and value will be + * trimmed. Contains the flag once the value has been trimmed. + * \param value - Where the value trimmed from the string will + * be stored. + */ + virtual void trimFlag( std::string& flag, std::string& value ) const; + + /** + * Checks whether a given string has blank chars, indicating that + * it is a combined SwitchArg. If so, return true, otherwise return + * false. + * \param s - string to be checked. + */ + bool _hasBlanks( const std::string& s ) const; + + /** + * Sets the requireLabel. Used by XorHandler. You shouldn't ever + * use this. + * \param s - Set the requireLabel to this value. + */ + void setRequireLabel( const std::string& s ); + + /** + * Used for MultiArgs and XorHandler to determine whether args + * can still be set. + */ + virtual bool allowMore(); + + /** + * Use by output classes to determine whether an Arg accepts + * multiple values. + */ + virtual bool acceptsMultipleValues(); + + /** + * Clears the Arg object and allows it to be reused by new + * command lines. + */ + virtual void reset(); +}; + +/** + * Typedef of an Arg list iterator. + */ +typedef std::list::iterator ArgListIterator; + +/** + * Typedef of an Arg vector iterator. + */ +typedef std::vector::iterator ArgVectorIterator; + +/** + * Typedef of a Visitor list iterator. + */ +typedef std::list::iterator VisitorListIterator; + +/* + * Extract a value of type T from it's string representation contained + * in strVal. The ValueLike parameter used to select the correct + * specialization of ExtractValue depending on the value traits of T. + * ValueLike traits use operator>> to assign the value from strVal. + */ +template void +ExtractValue(T &destVal, const std::string& strVal, ValueLike vl) +{ + static_cast(vl); // Avoid warning about unused vl + std::istringstream is(strVal); + + int valuesRead = 0; + while ( is.good() ) { + if ( is.peek() != EOF ) +#ifdef TCLAP_SETBASE_ZERO + is >> std::setbase(0) >> destVal; +#else + is >> destVal; +#endif + else + break; + + valuesRead++; + } + + if ( is.fail() ) + throw( ArgParseException("Couldn't read argument value " + "from string '" + strVal + "'")); + + + if ( valuesRead > 1 ) + throw( ArgParseException("More than one valid value parsed from " + "string '" + strVal + "'")); + +} + +/* + * Extract a value of type T from it's string representation contained + * in strVal. The ValueLike parameter used to select the correct + * specialization of ExtractValue depending on the value traits of T. + * StringLike uses assignment (operator=) to assign from strVal. + */ +template void +ExtractValue(T &destVal, const std::string& strVal, StringLike sl) +{ + static_cast(sl); // Avoid warning about unused sl + SetString(destVal, strVal); +} + +////////////////////////////////////////////////////////////////////// +//BEGIN Arg.cpp +////////////////////////////////////////////////////////////////////// + +inline Arg::Arg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + bool valreq, + Visitor* v) : + _flag(flag), + _name(name), + _description(desc), + _required(req), + _requireLabel("required"), + _valueRequired(valreq), + _alreadySet(false), + _visitor( v ), + _ignoreable(true), + _xorSet(false), + _acceptsMultipleValues(false) +{ + if ( _flag.length() > 1 ) + throw(SpecificationException( + "Argument flag can only be one character long", toString() ) ); + + if ( _name != ignoreNameString() && + ( _flag == Arg::flagStartString() || + _flag == Arg::nameStartString() || + _flag == " " ) ) + throw(SpecificationException("Argument flag cannot be either '" + + Arg::flagStartString() + "' or '" + + Arg::nameStartString() + "' or a space.", + toString() ) ); + + if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) || + ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) || + ( _name.find( " ", 0 ) != std::string::npos ) ) + throw(SpecificationException("Argument name begin with either '" + + Arg::flagStartString() + "' or '" + + Arg::nameStartString() + "' or space.", + toString() ) ); + +} + +inline Arg::~Arg() { } + +inline std::string Arg::shortID( const std::string& valueId ) const +{ + std::string id = ""; + + if ( _flag != "" ) + id = Arg::flagStartString() + _flag; + else + id = Arg::nameStartString() + _name; + + if ( _valueRequired ) + id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; + + if ( !_required ) + id = "[" + id + "]"; + + return id; +} + +inline std::string Arg::longID( const std::string& valueId ) const +{ + std::string id = ""; + + if ( _flag != "" ) + { + id += Arg::flagStartString() + _flag; + + if ( _valueRequired ) + id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; + + id += ", "; + } + + id += Arg::nameStartString() + _name; + + if ( _valueRequired ) + id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; + + return id; + +} + +inline bool Arg::operator==(const Arg& a) const +{ + if ( ( _flag != "" && _flag == a._flag ) || _name == a._name) + return true; + else + return false; +} + +inline std::string Arg::getDescription() const +{ + std::string desc = ""; + if ( _required ) + desc = "(" + _requireLabel + ") "; + +// if ( _valueRequired ) +// desc += "(value required) "; + + desc += _description; + return desc; +} + +inline const std::string& Arg::getFlag() const { return _flag; } + +inline const std::string& Arg::getName() const { return _name; } + +inline bool Arg::isRequired() const { return _required; } + +inline bool Arg::isValueRequired() const { return _valueRequired; } + +inline bool Arg::isSet() const +{ + if ( _alreadySet && !_xorSet ) + return true; + else + return false; +} + +inline bool Arg::isIgnoreable() const { return _ignoreable; } + +inline void Arg::setRequireLabel( const std::string& s) +{ + _requireLabel = s; +} + +inline bool Arg::argMatches( const std::string& argFlag ) const +{ + if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) || + argFlag == Arg::nameStartString() + _name ) + return true; + else + return false; +} + +inline std::string Arg::toString() const +{ + std::string s = ""; + + if ( _flag != "" ) + s += Arg::flagStartString() + _flag + " "; + + s += "(" + Arg::nameStartString() + _name + ")"; + + return s; +} + +inline void Arg::_checkWithVisitor() const +{ + if ( _visitor != NULL ) + _visitor->visit(); +} + +/** + * Implementation of trimFlag. + */ +inline void Arg::trimFlag(std::string& flag, std::string& value) const +{ + int stop = 0; + for ( int i = 0; static_cast(i) < flag.length(); i++ ) + if ( flag[i] == Arg::delimiter() ) + { + stop = i; + break; + } + + if ( stop > 1 ) + { + value = flag.substr(stop+1); + flag = flag.substr(0,stop); + } + +} + +/** + * Implementation of _hasBlanks. + */ +inline bool Arg::_hasBlanks( const std::string& s ) const +{ + for ( int i = 1; static_cast(i) < s.length(); i++ ) + if ( s[i] == Arg::blankChar() ) + return true; + + return false; +} + +inline void Arg::forceRequired() +{ + _required = true; +} + +inline void Arg::xorSet() +{ + _alreadySet = true; + _xorSet = true; +} + +/** + * Overridden by Args that need to added to the end of the list. + */ +inline void Arg::addToList( std::list& argList ) const +{ + argList.push_front( const_cast(this) ); +} + +inline bool Arg::allowMore() +{ + return false; +} + +inline bool Arg::acceptsMultipleValues() +{ + return _acceptsMultipleValues; +} + +inline void Arg::reset() +{ + _xorSet = false; + _alreadySet = false; +} + +////////////////////////////////////////////////////////////////////// +//END Arg.cpp +////////////////////////////////////////////////////////////////////// + +} //namespace TCLAP + +#endif + diff --git a/src/Menge/include/tclap/ArgException.h b/src/Menge/include/tclap/ArgException.h new file mode 100644 index 00000000..3411aa95 --- /dev/null +++ b/src/Menge/include/tclap/ArgException.h @@ -0,0 +1,200 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: ArgException.h + * + * Copyright (c) 2003, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_ARG_EXCEPTION_H +#define TCLAP_ARG_EXCEPTION_H + +#include +#include + +namespace TCLAP { + +/** + * A simple class that defines and argument exception. Should be caught + * whenever a CmdLine is created and parsed. + */ +class ArgException : public std::exception +{ + public: + + /** + * Constructor. + * \param text - The text of the exception. + * \param id - The text identifying the argument source. + * \param td - Text describing the type of ArgException it is. + * of the exception. + */ + ArgException( const std::string& text = "undefined exception", + const std::string& id = "undefined", + const std::string& td = "Generic ArgException") + : std::exception(), + _errorText(text), + _argId( id ), + _typeDescription(td) + { } + + /** + * Destructor. + */ + virtual ~ArgException() throw() { } + + /** + * Returns the error text. + */ + std::string error() const { return ( _errorText ); } + + /** + * Returns the argument id. + */ + std::string argId() const + { + if ( _argId == "undefined" ) + return " "; + else + return ( "Argument: " + _argId ); + } + + /** + * Returns the arg id and error text. + */ + const char* what() const throw() + { + static std::string ex; + ex = _argId + " -- " + _errorText; + return ex.c_str(); + } + + /** + * Returns the type of the exception. Used to explain and distinguish + * between different child exceptions. + */ + std::string typeDescription() const + { + return _typeDescription; + } + + + private: + + /** + * The text of the exception message. + */ + std::string _errorText; + + /** + * The argument related to this exception. + */ + std::string _argId; + + /** + * Describes the type of the exception. Used to distinguish + * between different child exceptions. + */ + std::string _typeDescription; + +}; + +/** + * Thrown from within the child Arg classes when it fails to properly + * parse the argument it has been passed. + */ +class ArgParseException : public ArgException +{ + public: + /** + * Constructor. + * \param text - The text of the exception. + * \param id - The text identifying the argument source + * of the exception. + */ + ArgParseException( const std::string& text = "undefined exception", + const std::string& id = "undefined" ) + : ArgException( text, + id, + std::string( "Exception found while parsing " ) + + std::string( "the value the Arg has been passed." )) + { } +}; + +/** + * Thrown from CmdLine when the arguments on the command line are not + * properly specified, e.g. too many arguments, required argument missing, etc. + */ +class CmdLineParseException : public ArgException +{ + public: + /** + * Constructor. + * \param text - The text of the exception. + * \param id - The text identifying the argument source + * of the exception. + */ + CmdLineParseException( const std::string& text = "undefined exception", + const std::string& id = "undefined" ) + : ArgException( text, + id, + std::string( "Exception found when the values ") + + std::string( "on the command line do not meet ") + + std::string( "the requirements of the defined ") + + std::string( "Args." )) + { } +}; + +/** + * Thrown from Arg and CmdLine when an Arg is improperly specified, e.g. + * same flag as another Arg, same name, etc. + */ +class SpecificationException : public ArgException +{ + public: + /** + * Constructor. + * \param text - The text of the exception. + * \param id - The text identifying the argument source + * of the exception. + */ + SpecificationException( const std::string& text = "undefined exception", + const std::string& id = "undefined" ) + : ArgException( text, + id, + std::string("Exception found when an Arg object ")+ + std::string("is improperly defined by the ") + + std::string("developer." )) + { } + +}; + +class ExitException { +public: + ExitException(int estat) : _estat(estat) {} + + int getExitStatus() const { return _estat; } + +private: + int _estat; +}; + +} // namespace TCLAP + +#endif + diff --git a/src/Menge/include/tclap/ArgTraits.h b/src/Menge/include/tclap/ArgTraits.h new file mode 100644 index 00000000..0b2c18f7 --- /dev/null +++ b/src/Menge/include/tclap/ArgTraits.h @@ -0,0 +1,87 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: ArgTraits.h + * + * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +// This is an internal tclap file, you should probably not have to +// include this directly + +#ifndef TCLAP_ARGTRAITS_H +#define TCLAP_ARGTRAITS_H + +namespace TCLAP { + +// We use two empty structs to get compile type specialization +// function to work + +/** + * A value like argument value type is a value that can be set using + * operator>>. This is the default value type. + */ +struct ValueLike { + typedef ValueLike ValueCategory; + virtual ~ValueLike() {} +}; + +/** + * A string like argument value type is a value that can be set using + * operator=(string). Usefull if the value type contains spaces which + * will be broken up into individual tokens by operator>>. + */ +struct StringLike { + virtual ~StringLike() {} +}; + +/** + * A class can inherit from this object to make it have string like + * traits. This is a compile time thing and does not add any overhead + * to the inherenting class. + */ +struct StringLikeTrait { + typedef StringLike ValueCategory; + virtual ~StringLikeTrait() {} +}; + +/** + * A class can inherit from this object to make it have value like + * traits. This is a compile time thing and does not add any overhead + * to the inherenting class. + */ +struct ValueLikeTrait { + typedef ValueLike ValueCategory; + virtual ~ValueLikeTrait() {} +}; + +/** + * Arg traits are used to get compile type specialization when parsing + * argument values. Using an ArgTraits you can specify the way that + * values gets assigned to any particular type during parsing. The two + * supported types are StringLike and ValueLike. + */ +template +struct ArgTraits { + typedef typename T::ValueCategory ValueCategory; + virtual ~ArgTraits() {} + //typedef ValueLike ValueCategory; +}; + +#endif + +} // namespace diff --git a/src/Menge/include/tclap/CmdLine.h b/src/Menge/include/tclap/CmdLine.h new file mode 100644 index 00000000..0fec8d8a --- /dev/null +++ b/src/Menge/include/tclap/CmdLine.h @@ -0,0 +1,633 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: CmdLine.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_CMDLINE_H +#define TCLAP_CMDLINE_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include // Needed for exit(), which isn't defined in some envs. + +namespace TCLAP { + +template void DelPtr(T ptr) +{ + delete ptr; +} + +template void ClearContainer(C &c) +{ + typedef typename C::value_type value_type; + std::for_each(c.begin(), c.end(), DelPtr); + c.clear(); +} + + +/** + * The base class that manages the command line definition and passes + * along the parsing to the appropriate Arg classes. + */ +class CmdLine : public CmdLineInterface +{ + protected: + + /** + * The list of arguments that will be tested against the + * command line. + */ + std::list _argList; + + /** + * The name of the program. Set to argv[0]. + */ + std::string _progName; + + /** + * A message used to describe the program. Used in the usage output. + */ + std::string _message; + + /** + * The version to be displayed with the --version switch. + */ + std::string _version; + + /** + * The number of arguments that are required to be present on + * the command line. This is set dynamically, based on the + * Args added to the CmdLine object. + */ + int _numRequired; + + /** + * The character that is used to separate the argument flag/name + * from the value. Defaults to ' ' (space). + */ + char _delimiter; + + /** + * The handler that manages xoring lists of args. + */ + XorHandler _xorHandler; + + /** + * A list of Args to be explicitly deleted when the destructor + * is called. At the moment, this only includes the three default + * Args. + */ + std::list _argDeleteOnExitList; + + /** + * A list of Visitors to be explicitly deleted when the destructor + * is called. At the moment, these are the Vistors created for the + * default Args. + */ + std::list _visitorDeleteOnExitList; + + /** + * Object that handles all output for the CmdLine. + */ + CmdLineOutput* _output; + + /** + * Should CmdLine handle parsing exceptions internally? + */ + bool _handleExceptions; + + /** + * Throws an exception listing the missing args. + */ + void missingArgsException(); + + /** + * Checks whether a name/flag string matches entirely matches + * the Arg::blankChar. Used when multiple switches are combined + * into a single argument. + * \param s - The message to be used in the usage. + */ + bool _emptyCombined(const std::string& s); + + /** + * Perform a delete ptr; operation on ptr when this object is deleted. + */ + void deleteOnExit(Arg* ptr); + + /** + * Perform a delete ptr; operation on ptr when this object is deleted. + */ + void deleteOnExit(Visitor* ptr); + +private: + + /** + * Prevent accidental copying. + */ + CmdLine(const CmdLine& rhs); + CmdLine& operator=(const CmdLine& rhs); + + /** + * Encapsulates the code common to the constructors + * (which is all of it). + */ + void _constructor(); + + + /** + * Is set to true when a user sets the output object. We use this so + * that we don't delete objects that are created outside of this lib. + */ + bool _userSetOutput; + + /** + * Whether or not to automatically create help and version switches. + */ + bool _helpAndVersion; + + public: + + /** + * Command line constructor. Defines how the arguments will be + * parsed. + * \param message - The message to be used in the usage + * output. + * \param delimiter - The character that is used to separate + * the argument flag/name from the value. Defaults to ' ' (space). + * \param version - The version number to be used in the + * --version switch. + * \param helpAndVersion - Whether or not to create the Help and + * Version switches. Defaults to true. + */ + CmdLine(const std::string& message, + const char delimiter = ' ', + const std::string& version = "none", + bool helpAndVersion = true); + + /** + * Deletes any resources allocated by a CmdLine object. + */ + virtual ~CmdLine(); + + /** + * Adds an argument to the list of arguments to be parsed. + * \param a - Argument to be added. + */ + void add( Arg& a ); + + /** + * An alternative add. Functionally identical. + * \param a - Argument to be added. + */ + void add( Arg* a ); + + /** + * Add two Args that will be xor'd. If this method is used, add does + * not need to be called. + * \param a - Argument to be added and xor'd. + * \param b - Argument to be added and xor'd. + */ + void xorAdd( Arg& a, Arg& b ); + + /** + * Add a list of Args that will be xor'd. If this method is used, + * add does not need to be called. + * \param xors - List of Args to be added and xor'd. + */ + void xorAdd( std::vector& xors ); + + /** + * Parses the command line. + * \param argc - Number of arguments. + * \param argv - Array of arguments. + */ + void parse(int argc, const char * const * argv); + + /** + * Parses the command line. + * \param args - A vector of strings representing the args. + * args[0] is still the program name. + */ + void parse(std::vector& args); + + /** + * + */ + CmdLineOutput* getOutput(); + + /** + * + */ + void setOutput(CmdLineOutput* co); + + /** + * + */ + std::string& getVersion(); + + /** + * + */ + std::string& getProgramName(); + + /** + * + */ + std::list& getArgList(); + + /** + * + */ + XorHandler& getXorHandler(); + + /** + * + */ + char getDelimiter(); + + /** + * + */ + std::string& getMessage(); + + /** + * + */ + bool hasHelpAndVersion(); + + /** + * Disables or enables CmdLine's internal parsing exception handling. + * + * @param state Should CmdLine handle parsing exceptions internally? + */ + void setExceptionHandling(const bool state); + + /** + * Returns the current state of the internal exception handling. + * + * @retval true Parsing exceptions are handled internally. + * @retval false Parsing exceptions are propagated to the caller. + */ + bool getExceptionHandling() const; + + /** + * Allows the CmdLine object to be reused. + */ + void reset(); + +}; + + +/////////////////////////////////////////////////////////////////////////////// +//Begin CmdLine.cpp +/////////////////////////////////////////////////////////////////////////////// + +inline CmdLine::CmdLine(const std::string& m, + char delim, + const std::string& v, + bool help ) + : + _argList(std::list()), + _progName("not_set_yet"), + _message(m), + _version(v), + _numRequired(0), + _delimiter(delim), + _xorHandler(XorHandler()), + _argDeleteOnExitList(std::list()), + _visitorDeleteOnExitList(std::list()), + _output(0), + _handleExceptions(true), + _userSetOutput(false), + _helpAndVersion(help) +{ + _constructor(); +} + +inline CmdLine::~CmdLine() +{ + ClearContainer(_argDeleteOnExitList); + ClearContainer(_visitorDeleteOnExitList); + + if ( !_userSetOutput ) { + delete _output; + _output = 0; + } +} + +inline void CmdLine::_constructor() +{ + _output = new StdOutput; + + Arg::setDelimiter( _delimiter ); + + Visitor* v; + + if ( _helpAndVersion ) + { + v = new HelpVisitor( this, &_output ); + SwitchArg* help = new SwitchArg("h","help", + "Displays usage information and exits.", + false, v); + add( help ); + deleteOnExit(help); + deleteOnExit(v); + + v = new VersionVisitor( this, &_output ); + SwitchArg* vers = new SwitchArg("","version", + "Displays version information and exits.", + false, v); + add( vers ); + deleteOnExit(vers); + deleteOnExit(v); + } + + v = new IgnoreRestVisitor(); + SwitchArg* ignore = new SwitchArg(Arg::flagStartString(), + Arg::ignoreNameString(), + "Ignores the rest of the labeled arguments following this flag.", + false, v); + add( ignore ); + deleteOnExit(ignore); + deleteOnExit(v); +} + +inline void CmdLine::xorAdd( std::vector& ors ) +{ + _xorHandler.add( ors ); + + for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++) + { + (*it)->forceRequired(); + (*it)->setRequireLabel( "OR required" ); + add( *it ); + } +} + +inline void CmdLine::xorAdd( Arg& a, Arg& b ) +{ + std::vector ors; + ors.push_back( &a ); + ors.push_back( &b ); + xorAdd( ors ); +} + +inline void CmdLine::add( Arg& a ) +{ + add( &a ); +} + +inline void CmdLine::add( Arg* a ) +{ + for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) + if ( *a == *(*it) ) + throw( SpecificationException( + "Argument with same flag/name already exists!", + a->longID() ) ); + + a->addToList( _argList ); + + if ( a->isRequired() ) + _numRequired++; +} + + +inline void CmdLine::parse(int argc, const char * const * argv) +{ + // this step is necessary so that we have easy access to + // mutable strings. + std::vector args; + for (int i = 0; i < argc; i++) + args.push_back(argv[i]); + + parse(args); +} + +inline void CmdLine::parse(std::vector& args) +{ + bool shouldExit = false; + int estat = 0; + + try { + _progName = args.front(); + args.erase(args.begin()); + + int requiredCount = 0; + + for (int i = 0; static_cast(i) < args.size(); i++) + { + bool matched = false; + for (ArgListIterator it = _argList.begin(); + it != _argList.end(); it++) { + if ( (*it)->processArg( &i, args ) ) + { + requiredCount += _xorHandler.check( *it ); + matched = true; + break; + } + } + + // checks to see if the argument is an empty combined + // switch and if so, then we've actually matched it + if ( !matched && _emptyCombined( args[i] ) ) + matched = true; + + if ( !matched && !Arg::ignoreRest() ) + throw(CmdLineParseException("Couldn't find match " + "for argument", + args[i])); + } + + if ( requiredCount < _numRequired ) + missingArgsException(); + + if ( requiredCount > _numRequired ) + throw(CmdLineParseException("Too many arguments!")); + + } catch ( ArgException& e ) { + // If we're not handling the exceptions, rethrow. + if ( !_handleExceptions) { + throw; + } + + try { + _output->failure(*this,e); + } catch ( ExitException &ee ) { + estat = ee.getExitStatus(); + shouldExit = true; + } + } catch (ExitException &ee) { + // If we're not handling the exceptions, rethrow. + if ( !_handleExceptions) { + throw; + } + + estat = ee.getExitStatus(); + shouldExit = true; + } + + if (shouldExit) + exit(estat); +} + +inline bool CmdLine::_emptyCombined(const std::string& s) +{ + if ( s.length() > 0 && s[0] != Arg::flagStartChar() ) + return false; + + for ( int i = 1; static_cast(i) < s.length(); i++ ) + if ( s[i] != Arg::blankChar() ) + return false; + + return true; +} + +inline void CmdLine::missingArgsException() +{ + int count = 0; + + std::string missingArgList; + for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++) + { + if ( (*it)->isRequired() && !(*it)->isSet() ) + { + missingArgList += (*it)->getName(); + missingArgList += ", "; + count++; + } + } + missingArgList = missingArgList.substr(0,missingArgList.length()-2); + + std::string msg; + if ( count > 1 ) + msg = "Required arguments missing: "; + else + msg = "Required argument missing: "; + + msg += missingArgList; + + throw(CmdLineParseException(msg)); +} + +inline void CmdLine::deleteOnExit(Arg* ptr) +{ + _argDeleteOnExitList.push_back(ptr); +} + +inline void CmdLine::deleteOnExit(Visitor* ptr) +{ + _visitorDeleteOnExitList.push_back(ptr); +} + +inline CmdLineOutput* CmdLine::getOutput() +{ + return _output; +} + +inline void CmdLine::setOutput(CmdLineOutput* co) +{ + if ( !_userSetOutput ) + delete _output; + _userSetOutput = true; + _output = co; +} + +inline std::string& CmdLine::getVersion() +{ + return _version; +} + +inline std::string& CmdLine::getProgramName() +{ + return _progName; +} + +inline std::list& CmdLine::getArgList() +{ + return _argList; +} + +inline XorHandler& CmdLine::getXorHandler() +{ + return _xorHandler; +} + +inline char CmdLine::getDelimiter() +{ + return _delimiter; +} + +inline std::string& CmdLine::getMessage() +{ + return _message; +} + +inline bool CmdLine::hasHelpAndVersion() +{ + return _helpAndVersion; +} + +inline void CmdLine::setExceptionHandling(const bool state) +{ + _handleExceptions = state; +} + +inline bool CmdLine::getExceptionHandling() const +{ + return _handleExceptions; +} + +inline void CmdLine::reset() +{ + for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) + (*it)->reset(); + + _progName.clear(); +} + +/////////////////////////////////////////////////////////////////////////////// +//End CmdLine.cpp +/////////////////////////////////////////////////////////////////////////////// + + + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tclap/CmdLineInterface.h b/src/Menge/include/tclap/CmdLineInterface.h new file mode 100644 index 00000000..1b25e9b8 --- /dev/null +++ b/src/Menge/include/tclap/CmdLineInterface.h @@ -0,0 +1,150 @@ + +/****************************************************************************** + * + * file: CmdLineInterface.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_COMMANDLINE_INTERFACE_H +#define TCLAP_COMMANDLINE_INTERFACE_H + +#include +#include +#include +#include +#include + + +namespace TCLAP { + +class Arg; +class CmdLineOutput; +class XorHandler; + +/** + * The base class that manages the command line definition and passes + * along the parsing to the appropriate Arg classes. + */ +class CmdLineInterface +{ + public: + + /** + * Destructor + */ + virtual ~CmdLineInterface() {} + + /** + * Adds an argument to the list of arguments to be parsed. + * \param a - Argument to be added. + */ + virtual void add( Arg& a )=0; + + /** + * An alternative add. Functionally identical. + * \param a - Argument to be added. + */ + virtual void add( Arg* a )=0; + + /** + * Add two Args that will be xor'd. + * If this method is used, add does + * not need to be called. + * \param a - Argument to be added and xor'd. + * \param b - Argument to be added and xor'd. + */ + virtual void xorAdd( Arg& a, Arg& b )=0; + + /** + * Add a list of Args that will be xor'd. If this method is used, + * add does not need to be called. + * \param xors - List of Args to be added and xor'd. + */ + virtual void xorAdd( std::vector& xors )=0; + + /** + * Parses the command line. + * \param argc - Number of arguments. + * \param argv - Array of arguments. + */ + virtual void parse(int argc, const char * const * argv)=0; + + /** + * Parses the command line. + * \param args - A vector of strings representing the args. + * args[0] is still the program name. + */ + void parse(std::vector& args); + + /** + * Returns the CmdLineOutput object. + */ + virtual CmdLineOutput* getOutput()=0; + + /** + * \param co - CmdLineOutput object that we want to use instead. + */ + virtual void setOutput(CmdLineOutput* co)=0; + + /** + * Returns the version string. + */ + virtual std::string& getVersion()=0; + + /** + * Returns the program name string. + */ + virtual std::string& getProgramName()=0; + + /** + * Returns the argList. + */ + virtual std::list& getArgList()=0; + + /** + * Returns the XorHandler. + */ + virtual XorHandler& getXorHandler()=0; + + /** + * Returns the delimiter string. + */ + virtual char getDelimiter()=0; + + /** + * Returns the message string. + */ + virtual std::string& getMessage()=0; + + /** + * Indicates whether or not the help and version switches were created + * automatically. + */ + virtual bool hasHelpAndVersion()=0; + + /** + * Resets the instance as if it had just been constructed so that the + * instance can be reused. + */ + virtual void reset()=0; +}; + +} //namespace + + +#endif diff --git a/src/Menge/include/tclap/CmdLineOutput.h b/src/Menge/include/tclap/CmdLineOutput.h new file mode 100644 index 00000000..71ee5a3b --- /dev/null +++ b/src/Menge/include/tclap/CmdLineOutput.h @@ -0,0 +1,74 @@ + + +/****************************************************************************** + * + * file: CmdLineOutput.h + * + * Copyright (c) 2004, Michael E. Smoot + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_CMDLINEOUTPUT_H +#define TCLAP_CMDLINEOUTPUT_H + +#include +#include +#include +#include +#include +#include + +namespace TCLAP { + +class CmdLineInterface; +class ArgException; + +/** + * The interface that any output object must implement. + */ +class CmdLineOutput +{ + + public: + + /** + * Virtual destructor. + */ + virtual ~CmdLineOutput() {} + + /** + * Generates some sort of output for the USAGE. + * \param c - The CmdLine object the output is generated for. + */ + virtual void usage(CmdLineInterface& c)=0; + + /** + * Generates some sort of output for the version. + * \param c - The CmdLine object the output is generated for. + */ + virtual void version(CmdLineInterface& c)=0; + + /** + * Generates some sort of output for a failure. + * \param c - The CmdLine object the output is generated for. + * \param e - The ArgException that caused the failure. + */ + virtual void failure( CmdLineInterface& c, + ArgException& e )=0; + +}; + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tclap/Constraint.h b/src/Menge/include/tclap/Constraint.h new file mode 100644 index 00000000..a92acf9a --- /dev/null +++ b/src/Menge/include/tclap/Constraint.h @@ -0,0 +1,68 @@ + +/****************************************************************************** + * + * file: Constraint.h + * + * Copyright (c) 2005, Michael E. Smoot + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_CONSTRAINT_H +#define TCLAP_CONSTRAINT_H + +#include +#include +#include +#include +#include +#include + +namespace TCLAP { + +/** + * The interface that defines the interaction between the Arg and Constraint. + */ +template +class Constraint +{ + + public: + /** + * Returns a description of the Constraint. + */ + virtual std::string description() const =0; + + /** + * Returns the short ID for the Constraint. + */ + virtual std::string shortID() const =0; + + /** + * The method used to verify that the value parsed from the command + * line meets the constraint. + * \param value - The value that will be checked. + */ + virtual bool check(const T& value) const =0; + + /** + * Destructor. + * Silences warnings about Constraint being a base class with virtual + * functions but without a virtual destructor. + */ + virtual ~Constraint() { ; } +}; + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tclap/DocBookOutput.h b/src/Menge/include/tclap/DocBookOutput.h new file mode 100644 index 00000000..a42ca274 --- /dev/null +++ b/src/Menge/include/tclap/DocBookOutput.h @@ -0,0 +1,299 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: DocBookOutput.h + * + * Copyright (c) 2004, Michael E. Smoot + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_DOCBOOKOUTPUT_H +#define TCLAP_DOCBOOKOUTPUT_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace TCLAP { + +/** + * A class that generates DocBook output for usage() method for the + * given CmdLine and its Args. + */ +class DocBookOutput : public CmdLineOutput +{ + + public: + + /** + * Prints the usage to stdout. Can be overridden to + * produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void usage(CmdLineInterface& c); + + /** + * Prints the version to stdout. Can be overridden + * to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void version(CmdLineInterface& c); + + /** + * Prints (to stderr) an error message, short usage + * Can be overridden to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + * \param e - The ArgException that caused the failure. + */ + virtual void failure(CmdLineInterface& c, + ArgException& e ); + + protected: + + /** + * Substitutes the char r for string x in string s. + * \param s - The string to operate on. + * \param r - The char to replace. + * \param x - What to replace r with. + */ + void substituteSpecialChars( std::string& s, char r, std::string& x ); + void removeChar( std::string& s, char r); + void basename( std::string& s ); + + void printShortArg(Arg* it); + void printLongArg(Arg* it); + + char theDelimiter; +}; + + +inline void DocBookOutput::version(CmdLineInterface& _cmd) +{ + std::cout << _cmd.getVersion() << std::endl; +} + +inline void DocBookOutput::usage(CmdLineInterface& _cmd ) +{ + std::list argList = _cmd.getArgList(); + std::string progName = _cmd.getProgramName(); + std::string xversion = _cmd.getVersion(); + theDelimiter = _cmd.getDelimiter(); + XorHandler xorHandler = _cmd.getXorHandler(); + std::vector< std::vector > xorList = xorHandler.getXorList(); + basename(progName); + + std::cout << "" << std::endl; + std::cout << "" << std::endl << std::endl; + + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "" << progName << "" << std::endl; + std::cout << "1" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "" << progName << "" << std::endl; + std::cout << "" << _cmd.getMessage() << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << progName << "" << std::endl; + + // xor + for ( int i = 0; (unsigned int)i < xorList.size(); i++ ) + { + std::cout << "" << std::endl; + for ( ArgVectorIterator it = xorList[i].begin(); + it != xorList[i].end(); it++ ) + printShortArg((*it)); + + std::cout << "" << std::endl; + } + + // rest of args + for (ArgListIterator it = argList.begin(); it != argList.end(); it++) + if ( !xorHandler.contains( (*it) ) ) + printShortArg((*it)); + + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "Description" << std::endl; + std::cout << "" << std::endl; + std::cout << _cmd.getMessage() << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "Options" << std::endl; + + std::cout << "" << std::endl; + + for (ArgListIterator it = argList.begin(); it != argList.end(); it++) + printLongArg((*it)); + + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "Version" << std::endl; + std::cout << "" << std::endl; + std::cout << xversion << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + +} + +inline void DocBookOutput::failure( CmdLineInterface& _cmd, + ArgException& e ) +{ + static_cast(_cmd); // unused + std::cout << e.what() << std::endl; + throw ExitException(1); +} + +inline void DocBookOutput::substituteSpecialChars( std::string& s, + char r, + std::string& x ) +{ + size_t p; + while ( (p = s.find_first_of(r)) != std::string::npos ) + { + s.erase(p,1); + s.insert(p,x); + } +} + +inline void DocBookOutput::removeChar( std::string& s, char r) +{ + size_t p; + while ( (p = s.find_first_of(r)) != std::string::npos ) + { + s.erase(p,1); + } +} + +inline void DocBookOutput::basename( std::string& s ) +{ + size_t p = s.find_last_of('/'); + if ( p != std::string::npos ) + { + s.erase(0, p + 1); + } +} + +inline void DocBookOutput::printShortArg(Arg* a) +{ + std::string lt = "<"; + std::string gt = ">"; + + std::string id = a->shortID(); + substituteSpecialChars(id,'<',lt); + substituteSpecialChars(id,'>',gt); + removeChar(id,'['); + removeChar(id,']'); + + std::string choice = "opt"; + if ( a->isRequired() ) + choice = "plain"; + + std::cout << "acceptsMultipleValues() ) + std::cout << " rep='repeat'"; + + + std::cout << '>'; + if ( !a->getFlag().empty() ) + std::cout << a->flagStartChar() << a->getFlag(); + else + std::cout << a->nameStartString() << a->getName(); + if ( a->isValueRequired() ) + { + std::string arg = a->shortID(); + removeChar(arg,'['); + removeChar(arg,']'); + removeChar(arg,'<'); + removeChar(arg,'>'); + arg.erase(0, arg.find_last_of(theDelimiter) + 1); + std::cout << theDelimiter; + std::cout << "" << arg << ""; + } + std::cout << "" << std::endl; + +} + +inline void DocBookOutput::printLongArg(Arg* a) +{ + std::string lt = "<"; + std::string gt = ">"; + + std::string desc = a->getDescription(); + substituteSpecialChars(desc,'<',lt); + substituteSpecialChars(desc,'>',gt); + + std::cout << "" << std::endl; + + if ( !a->getFlag().empty() ) + { + std::cout << "" << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + } + + std::cout << "" << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; + std::cout << "" << std::endl; + std::cout << desc << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + std::cout << "" << std::endl; +} + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tclap/HelpVisitor.h b/src/Menge/include/tclap/HelpVisitor.h new file mode 100644 index 00000000..cc3bd070 --- /dev/null +++ b/src/Menge/include/tclap/HelpVisitor.h @@ -0,0 +1,76 @@ + +/****************************************************************************** + * + * file: HelpVisitor.h + * + * Copyright (c) 2003, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_HELP_VISITOR_H +#define TCLAP_HELP_VISITOR_H + +#include +#include +#include + +namespace TCLAP { + +/** + * A Visitor object that calls the usage method of the given CmdLineOutput + * object for the specified CmdLine object. + */ +class HelpVisitor: public Visitor +{ + private: + /** + * Prevent accidental copying. + */ + HelpVisitor(const HelpVisitor& rhs); + HelpVisitor& operator=(const HelpVisitor& rhs); + + protected: + + /** + * The CmdLine the output will be generated for. + */ + CmdLineInterface* _cmd; + + /** + * The output object. + */ + CmdLineOutput** _out; + + public: + + /** + * Constructor. + * \param cmd - The CmdLine the output will be generated for. + * \param out - The type of output. + */ + HelpVisitor(CmdLineInterface* cmd, CmdLineOutput** out) + : Visitor(), _cmd( cmd ), _out( out ) { } + + /** + * Calls the usage method of the CmdLineOutput for the + * specified CmdLine. + */ + void visit() { (*_out)->usage(*_cmd); throw ExitException(0); } + +}; + +} + +#endif diff --git a/src/Menge/include/tclap/IgnoreRestVisitor.h b/src/Menge/include/tclap/IgnoreRestVisitor.h new file mode 100644 index 00000000..e328649e --- /dev/null +++ b/src/Menge/include/tclap/IgnoreRestVisitor.h @@ -0,0 +1,52 @@ + +/****************************************************************************** + * + * file: IgnoreRestVisitor.h + * + * Copyright (c) 2003, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_IGNORE_REST_VISITOR_H +#define TCLAP_IGNORE_REST_VISITOR_H + +#include +#include + +namespace TCLAP { + +/** + * A Vistor that tells the CmdLine to begin ignoring arguments after + * this one is parsed. + */ +class IgnoreRestVisitor: public Visitor +{ + public: + + /** + * Constructor. + */ + IgnoreRestVisitor() : Visitor() {} + + /** + * Sets Arg::_ignoreRest. + */ + void visit() { Arg::beginIgnoring(); } +}; + +} + +#endif diff --git a/src/Menge/include/tclap/MultiArg.h b/src/Menge/include/tclap/MultiArg.h new file mode 100644 index 00000000..34bb2d78 --- /dev/null +++ b/src/Menge/include/tclap/MultiArg.h @@ -0,0 +1,433 @@ +/****************************************************************************** + * + * file: MultiArg.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_MULTIPLE_ARGUMENT_H +#define TCLAP_MULTIPLE_ARGUMENT_H + +#include +#include + +#include +#include + +namespace TCLAP { +/** + * An argument that allows multiple values of type T to be specified. Very + * similar to a ValueArg, except a vector of values will be returned + * instead of just one. + */ +template +class MultiArg : public Arg +{ +public: + typedef std::vector container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + +protected: + + /** + * The list of values parsed from the CmdLine. + */ + std::vector _values; + + /** + * The description of type T to be used in the usage. + */ + std::string _typeDesc; + + /** + * A list of constraint on this Arg. + */ + Constraint* _constraint; + + /** + * Extracts the value from the string. + * Attempts to parse string as type T, if this fails an exception + * is thrown. + * \param val - The string to be read. + */ + void _extractValue( const std::string& val ); + + /** + * Used by XorHandler to decide whether to keep parsing for this arg. + */ + bool _allowMore; + +public: + + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + Visitor* v = NULL); + + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param parser - A CmdLine parser object to add this Arg to + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + CmdLineInterface& parser, + Visitor* v = NULL ); + + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + Visitor* v = NULL ); + + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param parser - A CmdLine parser object to add this Arg to + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + CmdLineInterface& parser, + Visitor* v = NULL ); + + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. It knows the difference + * between labeled and unlabeled. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed from main(). + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Returns a vector of type T containing the values parsed from + * the command line. + */ + const std::vector& getValue(); + + /** + * Returns an iterator over the values parsed from the command + * line. + */ + const_iterator begin() const { return _values.begin(); } + + /** + * Returns the end of the values parsed from the command + * line. + */ + const_iterator end() const { return _values.end(); } + + /** + * Returns the a short id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string shortID(const std::string& val="val") const; + + /** + * Returns the a long id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string longID(const std::string& val="val") const; + + /** + * Once we've matched the first value, then the arg is no longer + * required. + */ + virtual bool isRequired() const; + + virtual bool allowMore(); + + virtual void reset(); + +private: + /** + * Prevent accidental copying + */ + MultiArg(const MultiArg& rhs); + MultiArg& operator=(const MultiArg& rhs); + +}; + +template +MultiArg::MultiArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + Visitor* v) : + Arg( flag, name, desc, req, true, v ), + _values(std::vector()), + _typeDesc( typeDesc ), + _constraint( NULL ), + _allowMore(false) +{ + _acceptsMultipleValues = true; +} + +template +MultiArg::MultiArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + CmdLineInterface& parser, + Visitor* v) +: Arg( flag, name, desc, req, true, v ), + _values(std::vector()), + _typeDesc( typeDesc ), + _constraint( NULL ), + _allowMore(false) +{ + parser.add( this ); + _acceptsMultipleValues = true; +} + +/** + * + */ +template +MultiArg::MultiArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + Visitor* v) +: Arg( flag, name, desc, req, true, v ), + _values(std::vector()), + _typeDesc( constraint->shortID() ), + _constraint( constraint ), + _allowMore(false) +{ + _acceptsMultipleValues = true; +} + +template +MultiArg::MultiArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + CmdLineInterface& parser, + Visitor* v) +: Arg( flag, name, desc, req, true, v ), + _values(std::vector()), + _typeDesc( constraint->shortID() ), + _constraint( constraint ), + _allowMore(false) +{ + parser.add( this ); + _acceptsMultipleValues = true; +} + +template +const std::vector& MultiArg::getValue() { return _values; } + +template +bool MultiArg::processArg(int *i, std::vector& args) +{ + if ( _ignoreable && Arg::ignoreRest() ) + return false; + + if ( _hasBlanks( args[*i] ) ) + return false; + + std::string flag = args[*i]; + std::string value = ""; + + trimFlag( flag, value ); + + if ( argMatches( flag ) ) + { + if ( Arg::delimiter() != ' ' && value == "" ) + throw( ArgParseException( + "Couldn't find delimiter for this argument!", + toString() ) ); + + // always take the first one, regardless of start string + if ( value == "" ) + { + (*i)++; + if ( static_cast(*i) < args.size() ) + _extractValue( args[*i] ); + else + throw( ArgParseException("Missing a value for this argument!", + toString() ) ); + } + else + _extractValue( value ); + + /* + // continuing taking the args until we hit one with a start string + while ( (unsigned int)(*i)+1 < args.size() && + args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 && + args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 ) + _extractValue( args[++(*i)] ); + */ + + _alreadySet = true; + _checkWithVisitor(); + + return true; + } + else + return false; +} + +/** + * + */ +template +std::string MultiArg::shortID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return Arg::shortID(_typeDesc) + " ... "; +} + +/** + * + */ +template +std::string MultiArg::longID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return Arg::longID(_typeDesc) + " (accepted multiple times)"; +} + +/** + * Once we've matched the first value, then the arg is no longer + * required. + */ +template +bool MultiArg::isRequired() const +{ + if ( _required ) + { + if ( _values.size() > 1 ) + return false; + else + return true; + } + else + return false; + +} + +template +void MultiArg::_extractValue( const std::string& val ) +{ + try { + T tmp; + ExtractValue(tmp, val, typename ArgTraits::ValueCategory()); + _values.push_back(tmp); + } catch( ArgParseException &e) { + throw ArgParseException(e.error(), toString()); + } + + if ( _constraint != NULL ) + if ( ! _constraint->check( _values.back() ) ) + throw( CmdLineParseException( "Value '" + val + + "' does not meet constraint: " + + _constraint->description(), + toString() ) ); +} + +template +bool MultiArg::allowMore() +{ + bool am = _allowMore; + _allowMore = true; + return am; +} + +template +void MultiArg::reset() +{ + Arg::reset(); + _values.clear(); +} + +} // namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/MultiSwitchArg.h b/src/Menge/include/tclap/MultiSwitchArg.h new file mode 100644 index 00000000..8820b641 --- /dev/null +++ b/src/Menge/include/tclap/MultiSwitchArg.h @@ -0,0 +1,216 @@ + +/****************************************************************************** +* +* file: MultiSwitchArg.h +* +* Copyright (c) 2003, Michael E. Smoot . +* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. +* Copyright (c) 2005, Michael E. Smoot, Daniel Aarno, Erik Zeek. +* All rights reverved. +* +* See the file COPYING in the top directory of this distribution for +* more information. +* +* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + + +#ifndef TCLAP_MULTI_SWITCH_ARG_H +#define TCLAP_MULTI_SWITCH_ARG_H + +#include +#include + +#include + +namespace TCLAP { + +/** +* A multiple switch argument. If the switch is set on the command line, then +* the getValue method will return the number of times the switch appears. +*/ +class MultiSwitchArg : public SwitchArg +{ + protected: + + /** + * The value of the switch. + */ + int _value; + + /** + * Used to support the reset() method so that ValueArg can be + * reset to their constructed value. + */ + int _default; + + public: + + /** + * MultiSwitchArg constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param init - Optional. The initial/default value of this Arg. + * Defaults to 0. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiSwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + int init = 0, + Visitor* v = NULL); + + + /** + * MultiSwitchArg constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param parser - A CmdLine parser object to add this Arg to + * \param init - Optional. The initial/default value of this Arg. + * Defaults to 0. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiSwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + CmdLineInterface& parser, + int init = 0, + Visitor* v = NULL); + + + /** + * Handles the processing of the argument. + * This re-implements the SwitchArg version of this method to set the + * _value of the argument appropriately. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed + * in from main(). + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Returns int, the number of times the switch has been set. + */ + int getValue(); + + /** + * Returns the shortID for this Arg. + */ + std::string shortID(const std::string& val) const; + + /** + * Returns the longID for this Arg. + */ + std::string longID(const std::string& val) const; + + void reset(); + +}; + +////////////////////////////////////////////////////////////////////// +//BEGIN MultiSwitchArg.cpp +////////////////////////////////////////////////////////////////////// +inline MultiSwitchArg::MultiSwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + int init, + Visitor* v ) +: SwitchArg(flag, name, desc, false, v), +_value( init ), +_default( init ) +{ } + +inline MultiSwitchArg::MultiSwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + CmdLineInterface& parser, + int init, + Visitor* v ) +: SwitchArg(flag, name, desc, false, v), +_value( init ), +_default( init ) +{ + parser.add( this ); +} + +inline int MultiSwitchArg::getValue() { return _value; } + +inline bool MultiSwitchArg::processArg(int *i, std::vector& args) +{ + if ( _ignoreable && Arg::ignoreRest() ) + return false; + + if ( argMatches( args[*i] )) + { + // so the isSet() method will work + _alreadySet = true; + + // Matched argument: increment value. + ++_value; + + _checkWithVisitor(); + + return true; + } + else if ( combinedSwitchesMatch( args[*i] ) ) + { + // so the isSet() method will work + _alreadySet = true; + + // Matched argument: increment value. + ++_value; + + // Check for more in argument and increment value. + while ( combinedSwitchesMatch( args[*i] ) ) + ++_value; + + _checkWithVisitor(); + + return false; + } + else + return false; +} + +inline std::string +MultiSwitchArg::shortID(const std::string& val) const +{ + return Arg::shortID(val) + " ... "; +} + +inline std::string +MultiSwitchArg::longID(const std::string& val) const +{ + return Arg::longID(val) + " (accepted multiple times)"; +} + +inline void +MultiSwitchArg::reset() +{ + MultiSwitchArg::_value = MultiSwitchArg::_default; +} + +////////////////////////////////////////////////////////////////////// +//END MultiSwitchArg.cpp +////////////////////////////////////////////////////////////////////// + +} //namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/OptionalUnlabeledTracker.h b/src/Menge/include/tclap/OptionalUnlabeledTracker.h new file mode 100644 index 00000000..8174c5f6 --- /dev/null +++ b/src/Menge/include/tclap/OptionalUnlabeledTracker.h @@ -0,0 +1,62 @@ + + +/****************************************************************************** + * + * file: OptionalUnlabeledTracker.h + * + * Copyright (c) 2005, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_OPTIONAL_UNLABELED_TRACKER_H +#define TCLAP_OPTIONAL_UNLABELED_TRACKER_H + +#include + +namespace TCLAP { + +class OptionalUnlabeledTracker +{ + + public: + + static void check( bool req, const std::string& argName ); + + static void gotOptional() { alreadyOptionalRef() = true; } + + static bool& alreadyOptional() { return alreadyOptionalRef(); } + + private: + + static bool& alreadyOptionalRef() { static bool ct = false; return ct; } +}; + + +inline void OptionalUnlabeledTracker::check( bool req, const std::string& argName ) +{ + if ( OptionalUnlabeledTracker::alreadyOptional() ) + throw( SpecificationException( + "You can't specify ANY Unlabeled Arg following an optional Unlabeled Arg", + argName ) ); + + if ( !req ) + OptionalUnlabeledTracker::gotOptional(); +} + + +} // namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/StandardTraits.h b/src/Menge/include/tclap/StandardTraits.h new file mode 100644 index 00000000..46d7f6fa --- /dev/null +++ b/src/Menge/include/tclap/StandardTraits.h @@ -0,0 +1,208 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: StandardTraits.h + * + * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +// This is an internal tclap file, you should probably not have to +// include this directly + +#ifndef TCLAP_STANDARD_TRAITS_H +#define TCLAP_STANDARD_TRAITS_H + +#ifdef HAVE_CONFIG_H +#include // To check for long long +#endif + +// If Microsoft has already typedef'd wchar_t as an unsigned +// short, then compiles will break because it's as if we're +// creating ArgTraits twice for unsigned short. Thus... +#ifdef _MSC_VER +#ifndef _NATIVE_WCHAR_T_DEFINED +#define TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS +#endif +#endif + +namespace TCLAP { + +// ====================================================================== +// Integer types +// ====================================================================== + +/** + * longs have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * ints have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * shorts have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * chars have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +#ifdef HAVE_LONG_LONG +/** + * long longs have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; +#endif + +// ====================================================================== +// Unsigned integer types +// ====================================================================== + +/** + * unsigned longs have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * unsigned ints have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * unsigned shorts have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * unsigned chars have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +// Microsoft implements size_t awkwardly. +#if defined(_MSC_VER) && defined(_M_X64) +/** + * size_ts have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; +#endif + + +#ifdef HAVE_LONG_LONG +/** + * unsigned long longs have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; +#endif + +// ====================================================================== +// Float types +// ====================================================================== + +/** + * floats have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * doubles have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +// ====================================================================== +// Other types +// ====================================================================== + +/** + * bools have value-like semantics. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + + +/** + * wchar_ts have value-like semantics. + */ +#ifndef TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; +#endif + +/** + * Strings have string like argument traits. + */ +template<> +struct ArgTraits { + typedef StringLike ValueCategory; +}; + +template +void SetString(T &dst, const std::string &src) +{ + dst = src; +} + +} // namespace + +#endif + diff --git a/src/Menge/include/tclap/StdOutput.h b/src/Menge/include/tclap/StdOutput.h new file mode 100644 index 00000000..35f7b99b --- /dev/null +++ b/src/Menge/include/tclap/StdOutput.h @@ -0,0 +1,298 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: StdOutput.h + * + * Copyright (c) 2004, Michael E. Smoot + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_STDCMDLINEOUTPUT_H +#define TCLAP_STDCMDLINEOUTPUT_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace TCLAP { + +/** + * A class that isolates any output from the CmdLine object so that it + * may be easily modified. + */ +class StdOutput : public CmdLineOutput +{ + + public: + + /** + * Prints the usage to stdout. Can be overridden to + * produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void usage(CmdLineInterface& c); + + /** + * Prints the version to stdout. Can be overridden + * to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void version(CmdLineInterface& c); + + /** + * Prints (to stderr) an error message, short usage + * Can be overridden to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + * \param e - The ArgException that caused the failure. + */ + virtual void failure(CmdLineInterface& c, + ArgException& e ); + + protected: + + /** + * Writes a brief usage message with short args. + * \param c - The CmdLine object the output is generated for. + * \param os - The stream to write the message to. + */ + void _shortUsage( CmdLineInterface& c, std::ostream& os ) const; + + /** + * Writes a longer usage message with long and short args, + * provides descriptions and prints message. + * \param c - The CmdLine object the output is generated for. + * \param os - The stream to write the message to. + */ + void _longUsage( CmdLineInterface& c, std::ostream& os ) const; + + /** + * This function inserts line breaks and indents long strings + * according the params input. It will only break lines at spaces, + * commas and pipes. + * \param os - The stream to be printed to. + * \param s - The string to be printed. + * \param maxWidth - The maxWidth allowed for the output line. + * \param indentSpaces - The number of spaces to indent the first line. + * \param secondLineOffset - The number of spaces to indent the second + * and all subsequent lines in addition to indentSpaces. + */ + void spacePrint( std::ostream& os, + const std::string& s, + int maxWidth, + int indentSpaces, + int secondLineOffset ) const; + +}; + + +inline void StdOutput::version(CmdLineInterface& _cmd) +{ + std::string progName = _cmd.getProgramName(); + std::string xversion = _cmd.getVersion(); + + std::cout << std::endl << progName << " version: " + << xversion << std::endl << std::endl; +} + +inline void StdOutput::usage(CmdLineInterface& _cmd ) +{ + std::cout << std::endl << "USAGE: " << std::endl << std::endl; + + _shortUsage( _cmd, std::cout ); + + std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl; + + _longUsage( _cmd, std::cout ); + + std::cout << std::endl; + +} + +inline void StdOutput::failure( CmdLineInterface& _cmd, + ArgException& e ) +{ + std::string progName = _cmd.getProgramName(); + + std::cerr << "PARSE ERROR: " << e.argId() << std::endl + << " " << e.error() << std::endl << std::endl; + + if ( _cmd.hasHelpAndVersion() ) + { + std::cerr << "Brief USAGE: " << std::endl; + + _shortUsage( _cmd, std::cerr ); + + std::cerr << std::endl << "For complete USAGE and HELP type: " + << std::endl << " " << progName << " --help" + << std::endl << std::endl; + } + else + usage(_cmd); + + throw ExitException(1); +} + +inline void +StdOutput::_shortUsage( CmdLineInterface& _cmd, + std::ostream& os ) const +{ + std::list argList = _cmd.getArgList(); + std::string progName = _cmd.getProgramName(); + XorHandler xorHandler = _cmd.getXorHandler(); + std::vector< std::vector > xorList = xorHandler.getXorList(); + + std::string s = progName + " "; + + // first the xor + for ( int i = 0; static_cast(i) < xorList.size(); i++ ) + { + s += " {"; + for ( ArgVectorIterator it = xorList[i].begin(); + it != xorList[i].end(); it++ ) + s += (*it)->shortID() + "|"; + + s[s.length()-1] = '}'; + } + + // then the rest + for (ArgListIterator it = argList.begin(); it != argList.end(); it++) + if ( !xorHandler.contains( (*it) ) ) + s += " " + (*it)->shortID(); + + // if the program name is too long, then adjust the second line offset + int secondLineOffset = static_cast(progName.length()) + 2; + if ( secondLineOffset > 75/2 ) + secondLineOffset = static_cast(75/2); + + spacePrint( os, s, 75, 3, secondLineOffset ); +} + +inline void +StdOutput::_longUsage( CmdLineInterface& _cmd, + std::ostream& os ) const +{ + std::list argList = _cmd.getArgList(); + std::string message = _cmd.getMessage(); + XorHandler xorHandler = _cmd.getXorHandler(); + std::vector< std::vector > xorList = xorHandler.getXorList(); + + // first the xor + for ( int i = 0; static_cast(i) < xorList.size(); i++ ) + { + for ( ArgVectorIterator it = xorList[i].begin(); + it != xorList[i].end(); + it++ ) + { + spacePrint( os, (*it)->longID(), 75, 3, 3 ); + spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); + + if ( it+1 != xorList[i].end() ) + spacePrint(os, "-- OR --", 75, 9, 0); + } + os << std::endl << std::endl; + } + + // then the rest + for (ArgListIterator it = argList.begin(); it != argList.end(); it++) + if ( !xorHandler.contains( (*it) ) ) + { + spacePrint( os, (*it)->longID(), 75, 3, 3 ); + spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); + os << std::endl; + } + + os << std::endl; + + spacePrint( os, message, 75, 3, 0 ); +} + +inline void StdOutput::spacePrint( std::ostream& os, + const std::string& s, + int maxWidth, + int indentSpaces, + int secondLineOffset ) const +{ + int len = static_cast(s.length()); + + if ( (len + indentSpaces > maxWidth) && maxWidth > 0 ) + { + int allowedLen = maxWidth - indentSpaces; + int start = 0; + while ( start < len ) + { + // find the substring length + // int stringLen = std::min( len - start, allowedLen ); + // doing it this way to support a VisualC++ 2005 bug + using namespace std; + int stringLen = min( len - start, allowedLen ); + + // trim the length so it doesn't end in middle of a word + if ( stringLen == allowedLen ) + while ( stringLen >= 0 && + s[stringLen+start] != ' ' && + s[stringLen+start] != ',' && + s[stringLen+start] != '|' ) + stringLen--; + + // ok, the word is longer than the line, so just split + // wherever the line ends + if ( stringLen <= 0 ) + stringLen = allowedLen; + + // check for newlines + for ( int i = 0; i < stringLen; i++ ) + if ( s[start+i] == '\n' ) + stringLen = i+1; + + // print the indent + for ( int i = 0; i < indentSpaces; i++ ) + os << " "; + + if ( start == 0 ) + { + // handle second line offsets + indentSpaces += secondLineOffset; + + // adjust allowed len + allowedLen -= secondLineOffset; + } + + os << s.substr(start,stringLen) << std::endl; + + // so we don't start a line with a space + while ( s[stringLen+start] == ' ' && start < len ) + start++; + + start += stringLen; + } + } + else + { + for ( int i = 0; i < indentSpaces; i++ ) + os << " "; + os << s << std::endl; + } +} + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tclap/SwitchArg.h b/src/Menge/include/tclap/SwitchArg.h new file mode 100644 index 00000000..39161090 --- /dev/null +++ b/src/Menge/include/tclap/SwitchArg.h @@ -0,0 +1,266 @@ + +/****************************************************************************** + * + * file: SwitchArg.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_SWITCH_ARG_H +#define TCLAP_SWITCH_ARG_H + +#include +#include + +#include + +namespace TCLAP { + +/** + * A simple switch argument. If the switch is set on the command line, then + * the getValue method will return the opposite of the default value for the + * switch. + */ +class SwitchArg : public Arg +{ + protected: + + /** + * The value of the switch. + */ + bool _value; + + /** + * Used to support the reset() method so that ValueArg can be + * reset to their constructed value. + */ + bool _default; + + public: + + /** + * SwitchArg constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param def - The default value for this Switch. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + SwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool def = false, + Visitor* v = NULL); + + + /** + * SwitchArg constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param parser - A CmdLine parser object to add this Arg to + * \param def - The default value for this Switch. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + SwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + CmdLineInterface& parser, + bool def = false, + Visitor* v = NULL); + + + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed + * in from main(). + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Checks a string to see if any of the chars in the string + * match the flag for this Switch. + */ + bool combinedSwitchesMatch(std::string& combined); + + /** + * Returns bool, whether or not the switch has been set. + */ + bool getValue(); + + virtual void reset(); + + private: + /** + * Checks to see if we've found the last match in + * a combined string. + */ + bool lastCombined(std::string& combined); + + /** + * Does the common processing of processArg. + */ + void commonProcessing(); +}; + +////////////////////////////////////////////////////////////////////// +//BEGIN SwitchArg.cpp +////////////////////////////////////////////////////////////////////// +inline SwitchArg::SwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool default_val, + Visitor* v ) +: Arg(flag, name, desc, false, false, v), + _value( default_val ), + _default( default_val ) +{ } + +inline SwitchArg::SwitchArg(const std::string& flag, + const std::string& name, + const std::string& desc, + CmdLineInterface& parser, + bool default_val, + Visitor* v ) +: Arg(flag, name, desc, false, false, v), + _value( default_val ), + _default(default_val) +{ + parser.add( this ); +} + +inline bool SwitchArg::getValue() { return _value; } + +inline bool SwitchArg::lastCombined(std::string& combinedSwitches ) +{ + for ( unsigned int i = 1; i < combinedSwitches.length(); i++ ) + if ( combinedSwitches[i] != Arg::blankChar() ) + return false; + + return true; +} + +inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches ) +{ + // make sure this is actually a combined switch + if ( combinedSwitches.length() > 0 && + combinedSwitches[0] != Arg::flagStartString()[0] ) + return false; + + // make sure it isn't a long name + if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) == + Arg::nameStartString() ) + return false; + + // make sure the delimiter isn't in the string + if ( combinedSwitches.find_first_of( Arg::delimiter() ) != std::string::npos ) + return false; + + // ok, we're not specifying a ValueArg, so we know that we have + // a combined switch list. + for ( unsigned int i = 1; i < combinedSwitches.length(); i++ ) + if ( _flag.length() > 0 && + combinedSwitches[i] == _flag[0] && + _flag[0] != Arg::flagStartString()[0] ) + { + // update the combined switches so this one is no longer present + // this is necessary so that no unlabeled args are matched + // later in the processing. + //combinedSwitches.erase(i,1); + combinedSwitches[i] = Arg::blankChar(); + return true; + } + + // none of the switches passed in the list match. + return false; +} + +inline void SwitchArg::commonProcessing() +{ + if ( _xorSet ) + throw(CmdLineParseException( + "Mutually exclusive argument already set!", toString())); + + if ( _alreadySet ) + throw(CmdLineParseException("Argument already set!", toString())); + + _alreadySet = true; + + if ( _value == true ) + _value = false; + else + _value = true; + + _checkWithVisitor(); +} + +inline bool SwitchArg::processArg(int *i, std::vector& args) +{ + if ( _ignoreable && Arg::ignoreRest() ) + return false; + + // if the whole string matches the flag or name string + if ( argMatches( args[*i] ) ) + { + commonProcessing(); + + return true; + } + // if a substring matches the flag as part of a combination + else if ( combinedSwitchesMatch( args[*i] ) ) + { + // check again to ensure we don't misinterpret + // this as a MultiSwitchArg + if ( combinedSwitchesMatch( args[*i] ) ) + throw(CmdLineParseException("Argument already set!", + toString())); + + commonProcessing(); + + // We only want to return true if we've found the last combined + // match in the string, otherwise we return true so that other + // switches in the combination will have a chance to match. + return lastCombined( args[*i] ); + } + else + return false; +} + +inline void SwitchArg::reset() +{ + Arg::reset(); + _value = _default; +} +////////////////////////////////////////////////////////////////////// +//End SwitchArg.cpp +////////////////////////////////////////////////////////////////////// + +} //namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/UnlabeledMultiArg.h b/src/Menge/include/tclap/UnlabeledMultiArg.h new file mode 100644 index 00000000..d5e17810 --- /dev/null +++ b/src/Menge/include/tclap/UnlabeledMultiArg.h @@ -0,0 +1,301 @@ + +/****************************************************************************** + * + * file: UnlabeledMultiArg.h + * + * Copyright (c) 2003, Michael E. Smoot. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H +#define TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H + +#include +#include + +#include +#include + +namespace TCLAP { + +/** + * Just like a MultiArg, except that the arguments are unlabeled. Basically, + * this Arg will slurp up everything that hasn't been matched to another + * Arg. + */ +template +class UnlabeledMultiArg : public MultiArg +{ + + // If compiler has two stage name lookup (as gcc >= 3.4 does) + // this is requried to prevent undef. symbols + using MultiArg::_ignoreable; + using MultiArg::_hasBlanks; + using MultiArg::_extractValue; + using MultiArg::_typeDesc; + using MultiArg::_name; + using MultiArg::_description; + using MultiArg::_alreadySet; + using MultiArg::toString; + + public: + + /** + * Constructor. + * \param name - The name of the Arg. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param ignoreable - Whether or not this argument can be ignored + * using the "--" flag. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + UnlabeledMultiArg( const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + bool ignoreable = false, + Visitor* v = NULL ); + /** + * Constructor. + * \param name - The name of the Arg. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param parser - A CmdLine parser object to add this Arg to + * \param ignoreable - Whether or not this argument can be ignored + * using the "--" flag. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + UnlabeledMultiArg( const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + CmdLineInterface& parser, + bool ignoreable = false, + Visitor* v = NULL ); + + /** + * Constructor. + * \param name - The name of the Arg. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param ignoreable - Whether or not this argument can be ignored + * using the "--" flag. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + UnlabeledMultiArg( const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + bool ignoreable = false, + Visitor* v = NULL ); + + /** + * Constructor. + * \param name - The name of the Arg. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param parser - A CmdLine parser object to add this Arg to + * \param ignoreable - Whether or not this argument can be ignored + * using the "--" flag. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + UnlabeledMultiArg( const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + CmdLineInterface& parser, + bool ignoreable = false, + Visitor* v = NULL ); + + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. It knows the difference + * between labeled and unlabeled. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed from main(). + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Returns the a short id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string shortID(const std::string& val="val") const; + + /** + * Returns the a long id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string longID(const std::string& val="val") const; + + /** + * Opertor ==. + * \param a - The Arg to be compared to this. + */ + virtual bool operator==(const Arg& a) const; + + /** + * Pushes this to back of list rather than front. + * \param argList - The list this should be added to. + */ + virtual void addToList( std::list& argList ) const; +}; + +template +UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + bool ignoreable, + Visitor* v) +: MultiArg("", name, desc, req, typeDesc, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(true, toString()); +} + +template +UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, + const std::string& desc, + bool req, + const std::string& typeDesc, + CmdLineInterface& parser, + bool ignoreable, + Visitor* v) +: MultiArg("", name, desc, req, typeDesc, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(true, toString()); + parser.add( this ); +} + + +template +UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + bool ignoreable, + Visitor* v) +: MultiArg("", name, desc, req, constraint, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(true, toString()); +} + +template +UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, + const std::string& desc, + bool req, + Constraint* constraint, + CmdLineInterface& parser, + bool ignoreable, + Visitor* v) +: MultiArg("", name, desc, req, constraint, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(true, toString()); + parser.add( this ); +} + + +template +bool UnlabeledMultiArg::processArg(int *i, std::vector& args) +{ + + if ( _hasBlanks( args[*i] ) ) + return false; + + // never ignore an unlabeled multi arg + + + // always take the first value, regardless of the start string + _extractValue( args[(*i)] ); + + /* + // continue taking args until we hit the end or a start string + while ( (unsigned int)(*i)+1 < args.size() && + args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 && + args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 ) + _extractValue( args[++(*i)] ); + */ + + _alreadySet = true; + + return true; +} + +template +std::string UnlabeledMultiArg::shortID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return std::string("<") + _typeDesc + "> ..."; +} + +template +std::string UnlabeledMultiArg::longID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return std::string("<") + _typeDesc + "> (accepted multiple times)"; +} + +template +bool UnlabeledMultiArg::operator==(const Arg& a) const +{ + if ( _name == a.getName() || _description == a.getDescription() ) + return true; + else + return false; +} + +template +void UnlabeledMultiArg::addToList( std::list& argList ) const +{ + argList.push_back( const_cast(static_cast(this)) ); +} + +} + +#endif diff --git a/src/Menge/include/tclap/UnlabeledValueArg.h b/src/Menge/include/tclap/UnlabeledValueArg.h new file mode 100644 index 00000000..5721d612 --- /dev/null +++ b/src/Menge/include/tclap/UnlabeledValueArg.h @@ -0,0 +1,340 @@ + +/****************************************************************************** + * + * file: UnlabeledValueArg.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_UNLABELED_VALUE_ARGUMENT_H +#define TCLAP_UNLABELED_VALUE_ARGUMENT_H + +#include +#include + +#include +#include + + +namespace TCLAP { + +/** + * The basic unlabeled argument that parses a value. + * This is a template class, which means the type T defines the type + * that a given object will attempt to parse when an UnlabeledValueArg + * is reached in the list of args that the CmdLine iterates over. + */ +template +class UnlabeledValueArg : public ValueArg +{ + + // If compiler has two stage name lookup (as gcc >= 3.4 does) + // this is requried to prevent undef. symbols + using ValueArg::_ignoreable; + using ValueArg::_hasBlanks; + using ValueArg::_extractValue; + using ValueArg::_typeDesc; + using ValueArg::_name; + using ValueArg::_description; + using ValueArg::_alreadySet; + using ValueArg::toString; + + public: + + /** + * UnlabeledValueArg constructor. + * \param name - A one word name for the argument. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param ignoreable - Allows you to specify that this argument can be + * ignored if the '--' flag is set. This defaults to false (cannot + * be ignored) and should generally stay that way unless you have + * some special need for certain arguments to be ignored. + * \param v - Optional Vistor. You should leave this blank unless + * you have a very good reason. + */ + UnlabeledValueArg( const std::string& name, + const std::string& desc, + bool req, + T value, + const std::string& typeDesc, + bool ignoreable = false, + Visitor* v = NULL); + + /** + * UnlabeledValueArg constructor. + * \param name - A one word name for the argument. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param parser - A CmdLine parser object to add this Arg to + * \param ignoreable - Allows you to specify that this argument can be + * ignored if the '--' flag is set. This defaults to false (cannot + * be ignored) and should generally stay that way unless you have + * some special need for certain arguments to be ignored. + * \param v - Optional Vistor. You should leave this blank unless + * you have a very good reason. + */ + UnlabeledValueArg( const std::string& name, + const std::string& desc, + bool req, + T value, + const std::string& typeDesc, + CmdLineInterface& parser, + bool ignoreable = false, + Visitor* v = NULL ); + + /** + * UnlabeledValueArg constructor. + * \param name - A one word name for the argument. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param ignoreable - Allows you to specify that this argument can be + * ignored if the '--' flag is set. This defaults to false (cannot + * be ignored) and should generally stay that way unless you have + * some special need for certain arguments to be ignored. + * \param v - Optional Vistor. You should leave this blank unless + * you have a very good reason. + */ + UnlabeledValueArg( const std::string& name, + const std::string& desc, + bool req, + T value, + Constraint* constraint, + bool ignoreable = false, + Visitor* v = NULL ); + + + /** + * UnlabeledValueArg constructor. + * \param name - A one word name for the argument. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param parser - A CmdLine parser object to add this Arg to + * \param ignoreable - Allows you to specify that this argument can be + * ignored if the '--' flag is set. This defaults to false (cannot + * be ignored) and should generally stay that way unless you have + * some special need for certain arguments to be ignored. + * \param v - Optional Vistor. You should leave this blank unless + * you have a very good reason. + */ + UnlabeledValueArg( const std::string& name, + const std::string& desc, + bool req, + T value, + Constraint* constraint, + CmdLineInterface& parser, + bool ignoreable = false, + Visitor* v = NULL); + + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. Handling specific to + * unlabled arguments. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Overrides shortID for specific behavior. + */ + virtual std::string shortID(const std::string& val="val") const; + + /** + * Overrides longID for specific behavior. + */ + virtual std::string longID(const std::string& val="val") const; + + /** + * Overrides operator== for specific behavior. + */ + virtual bool operator==(const Arg& a ) const; + + /** + * Instead of pushing to the front of list, push to the back. + * \param argList - The list to add this to. + */ + virtual void addToList( std::list& argList ) const; + +}; + +/** + * Constructor implemenation. + */ +template +UnlabeledValueArg::UnlabeledValueArg(const std::string& name, + const std::string& desc, + bool req, + T val, + const std::string& typeDesc, + bool ignoreable, + Visitor* v) +: ValueArg("", name, desc, req, val, typeDesc, v) +{ + _ignoreable = ignoreable; + + OptionalUnlabeledTracker::check(req, toString()); + +} + +template +UnlabeledValueArg::UnlabeledValueArg(const std::string& name, + const std::string& desc, + bool req, + T val, + const std::string& typeDesc, + CmdLineInterface& parser, + bool ignoreable, + Visitor* v) +: ValueArg("", name, desc, req, val, typeDesc, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(req, toString()); + parser.add( this ); +} + +/** + * Constructor implemenation. + */ +template +UnlabeledValueArg::UnlabeledValueArg(const std::string& name, + const std::string& desc, + bool req, + T val, + Constraint* constraint, + bool ignoreable, + Visitor* v) +: ValueArg("", name, desc, req, val, constraint, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(req, toString()); +} + +template +UnlabeledValueArg::UnlabeledValueArg(const std::string& name, + const std::string& desc, + bool req, + T val, + Constraint* constraint, + CmdLineInterface& parser, + bool ignoreable, + Visitor* v) +: ValueArg("", name, desc, req, val, constraint, v) +{ + _ignoreable = ignoreable; + OptionalUnlabeledTracker::check(req, toString()); + parser.add( this ); +} + +/** + * Implementation of processArg(). + */ +template +bool UnlabeledValueArg::processArg(int *i, std::vector& args) +{ + + if ( _alreadySet ) + return false; + + if ( _hasBlanks( args[*i] ) ) + return false; + + // never ignore an unlabeled arg + + _extractValue( args[*i] ); + _alreadySet = true; + return true; +} + +/** + * Overriding shortID for specific output. + */ +template +std::string UnlabeledValueArg::shortID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return std::string("<") + _typeDesc + ">"; +} + +/** + * Overriding longID for specific output. + */ +template +std::string UnlabeledValueArg::longID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + + // Ideally we would like to be able to use RTTI to return the name + // of the type required for this argument. However, g++ at least, + // doesn't appear to return terribly useful "names" of the types. + return std::string("<") + _typeDesc + ">"; +} + +/** + * Overriding operator== for specific behavior. + */ +template +bool UnlabeledValueArg::operator==(const Arg& a ) const +{ + if ( _name == a.getName() || _description == a.getDescription() ) + return true; + else + return false; +} + +template +void UnlabeledValueArg::addToList( std::list& argList ) const +{ + argList.push_back( const_cast(static_cast(this)) ); +} + +} +#endif diff --git a/src/Menge/include/tclap/ValueArg.h b/src/Menge/include/tclap/ValueArg.h new file mode 100644 index 00000000..7ac29526 --- /dev/null +++ b/src/Menge/include/tclap/ValueArg.h @@ -0,0 +1,425 @@ +/****************************************************************************** + * + * file: ValueArg.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_VALUE_ARGUMENT_H +#define TCLAP_VALUE_ARGUMENT_H + +#include +#include + +#include +#include + +namespace TCLAP { + +/** + * The basic labeled argument that parses a value. + * This is a template class, which means the type T defines the type + * that a given object will attempt to parse when the flag/name is matched + * on the command line. While there is nothing stopping you from creating + * an unflagged ValueArg, it is unwise and would cause significant problems. + * Instead use an UnlabeledValueArg. + */ +template +class ValueArg : public Arg +{ + protected: + + /** + * The value parsed from the command line. + * Can be of any type, as long as the >> operator for the type + * is defined. + */ + T _value; + + /** + * Used to support the reset() method so that ValueArg can be + * reset to their constructed value. + */ + T _default; + + /** + * A human readable description of the type to be parsed. + * This is a hack, plain and simple. Ideally we would use RTTI to + * return the name of type T, but until there is some sort of + * consistent support for human readable names, we are left to our + * own devices. + */ + std::string _typeDesc; + + /** + * A Constraint this Arg must conform to. + */ + Constraint* _constraint; + + /** + * Extracts the value from the string. + * Attempts to parse string as type T, if this fails an exception + * is thrown. + * \param val - value to be parsed. + */ + void _extractValue( const std::string& val ); + + public: + + /** + * Labeled ValueArg constructor. + * You could conceivably call this constructor with a blank flag, + * but that would make you a bad person. It would also cause + * an exception to be thrown. If you want an unlabeled argument, + * use the other constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + ValueArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T value, + const std::string& typeDesc, + Visitor* v = NULL); + + + /** + * Labeled ValueArg constructor. + * You could conceivably call this constructor with a blank flag, + * but that would make you a bad person. It would also cause + * an exception to be thrown. If you want an unlabeled argument, + * use the other constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param parser - A CmdLine parser object to add this Arg to + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + ValueArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T value, + const std::string& typeDesc, + CmdLineInterface& parser, + Visitor* v = NULL ); + + /** + * Labeled ValueArg constructor. + * You could conceivably call this constructor with a blank flag, + * but that would make you a bad person. It would also cause + * an exception to be thrown. If you want an unlabeled argument, + * use the other constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param parser - A CmdLine parser object to add this Arg to. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + ValueArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T value, + Constraint* constraint, + CmdLineInterface& parser, + Visitor* v = NULL ); + + /** + * Labeled ValueArg constructor. + * You could conceivably call this constructor with a blank flag, + * but that would make you a bad person. It would also cause + * an exception to be thrown. If you want an unlabeled argument, + * use the other constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + ValueArg( const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T value, + Constraint* constraint, + Visitor* v = NULL ); + + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. It knows the difference + * between labeled and unlabeled. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed + * in from main(). + */ + virtual bool processArg(int* i, std::vector& args); + + /** + * Returns the value of the argument. + */ + T& getValue() ; + + /** + * Specialization of shortID. + * \param val - value to be used. + */ + virtual std::string shortID(const std::string& val = "val") const; + + /** + * Specialization of longID. + * \param val - value to be used. + */ + virtual std::string longID(const std::string& val = "val") const; + + virtual void reset() ; + +private: + /** + * Prevent accidental copying + */ + ValueArg(const ValueArg& rhs); + ValueArg& operator=(const ValueArg& rhs); +}; + + +/** + * Constructor implementation. + */ +template +ValueArg::ValueArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T val, + const std::string& typeDesc, + Visitor* v) +: Arg(flag, name, desc, req, true, v), + _value( val ), + _default( val ), + _typeDesc( typeDesc ), + _constraint( NULL ) +{ } + +template +ValueArg::ValueArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T val, + const std::string& typeDesc, + CmdLineInterface& parser, + Visitor* v) +: Arg(flag, name, desc, req, true, v), + _value( val ), + _default( val ), + _typeDesc( typeDesc ), + _constraint( NULL ) +{ + parser.add( this ); +} + +template +ValueArg::ValueArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T val, + Constraint* constraint, + Visitor* v) +: Arg(flag, name, desc, req, true, v), + _value( val ), + _default( val ), + _typeDesc( constraint->shortID() ), + _constraint( constraint ) +{ } + +template +ValueArg::ValueArg(const std::string& flag, + const std::string& name, + const std::string& desc, + bool req, + T val, + Constraint* constraint, + CmdLineInterface& parser, + Visitor* v) +: Arg(flag, name, desc, req, true, v), + _value( val ), + _default( val ), + _typeDesc( constraint->shortID() ), + _constraint( constraint ) +{ + parser.add( this ); +} + + +/** + * Implementation of getValue(). + */ +template +T& ValueArg::getValue() { return _value; } + +/** + * Implementation of processArg(). + */ +template +bool ValueArg::processArg(int *i, std::vector& args) +{ + if ( _ignoreable && Arg::ignoreRest() ) + return false; + + if ( _hasBlanks( args[*i] ) ) + return false; + + std::string flag = args[*i]; + + std::string value = ""; + trimFlag( flag, value ); + + if ( argMatches( flag ) ) + { + if ( _alreadySet ) + { + if ( _xorSet ) + throw( CmdLineParseException( + "Mutually exclusive argument already set!", + toString()) ); + else + throw( CmdLineParseException("Argument already set!", + toString()) ); + } + + if ( Arg::delimiter() != ' ' && value == "" ) + throw( ArgParseException( + "Couldn't find delimiter for this argument!", + toString() ) ); + + if ( value == "" ) + { + (*i)++; + if ( static_cast(*i) < args.size() ) + _extractValue( args[*i] ); + else + throw( ArgParseException("Missing a value for this argument!", + toString() ) ); + } + else + _extractValue( value ); + + _alreadySet = true; + _checkWithVisitor(); + return true; + } + else + return false; +} + +/** + * Implementation of shortID. + */ +template +std::string ValueArg::shortID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return Arg::shortID( _typeDesc ); +} + +/** + * Implementation of longID. + */ +template +std::string ValueArg::longID(const std::string& val) const +{ + static_cast(val); // Ignore input, don't warn + return Arg::longID( _typeDesc ); +} + +template +void ValueArg::_extractValue( const std::string& val ) +{ + try { + ExtractValue(_value, val, typename ArgTraits::ValueCategory()); + } catch( ArgParseException &e) { + throw ArgParseException(e.error(), toString()); + } + + if ( _constraint != NULL ) + if ( ! _constraint->check( _value ) ) + throw( CmdLineParseException( "Value '" + val + + + "' does not meet constraint: " + + _constraint->description(), + toString() ) ); +} + +template +void ValueArg::reset() +{ + Arg::reset(); + _value = _default; +} + +} // namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/ValuesConstraint.h b/src/Menge/include/tclap/ValuesConstraint.h new file mode 100644 index 00000000..cb41f645 --- /dev/null +++ b/src/Menge/include/tclap/ValuesConstraint.h @@ -0,0 +1,148 @@ + + +/****************************************************************************** + * + * file: ValuesConstraint.h + * + * Copyright (c) 2005, Michael E. Smoot + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_VALUESCONSTRAINT_H +#define TCLAP_VALUESCONSTRAINT_H + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#else +#define HAVE_SSTREAM +#endif + +#if defined(HAVE_SSTREAM) +#include +#elif defined(HAVE_STRSTREAM) +#include +#else +#error "Need a stringstream (sstream or strstream) to compile!" +#endif + +namespace TCLAP { + +/** + * A Constraint that constrains the Arg to only those values specified + * in the constraint. + */ +template +class ValuesConstraint : public Constraint +{ + + public: + + /** + * Constructor. + * \param allowed - vector of allowed values. + */ + ValuesConstraint(std::vector& allowed); + + /** + * Virtual destructor. + */ + virtual ~ValuesConstraint() {} + + /** + * Returns a description of the Constraint. + */ + virtual std::string description() const; + + /** + * Returns the short ID for the Constraint. + */ + virtual std::string shortID() const; + + /** + * The method used to verify that the value parsed from the command + * line meets the constraint. + * \param value - The value that will be checked. + */ + virtual bool check(const T& value) const; + + protected: + + /** + * The list of valid values. + */ + std::vector _allowed; + + /** + * The string used to describe the allowed values of this constraint. + */ + std::string _typeDesc; + +}; + +template +ValuesConstraint::ValuesConstraint(std::vector& allowed) +: _allowed(allowed), + _typeDesc("") +{ + for ( unsigned int i = 0; i < _allowed.size(); i++ ) + { + +#if defined(HAVE_SSTREAM) + std::ostringstream os; +#elif defined(HAVE_STRSTREAM) + std::ostrstream os; +#else +#error "Need a stringstream (sstream or strstream) to compile!" +#endif + + os << _allowed[i]; + + std::string temp( os.str() ); + + if ( i > 0 ) + _typeDesc += "|"; + _typeDesc += temp; + } +} + +template +bool ValuesConstraint::check( const T& val ) const +{ + if ( std::find(_allowed.begin(),_allowed.end(),val) == _allowed.end() ) + return false; + else + return true; +} + +template +std::string ValuesConstraint::shortID() const +{ + return _typeDesc; +} + +template +std::string ValuesConstraint::description() const +{ + return _typeDesc; +} + + +} //namespace TCLAP +#endif + diff --git a/src/Menge/include/tclap/VersionVisitor.h b/src/Menge/include/tclap/VersionVisitor.h new file mode 100644 index 00000000..c110d4fa --- /dev/null +++ b/src/Menge/include/tclap/VersionVisitor.h @@ -0,0 +1,81 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: VersionVisitor.h + * + * Copyright (c) 2003, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_VERSION_VISITOR_H +#define TCLAP_VERSION_VISITOR_H + +#include +#include +#include + +namespace TCLAP { + +/** + * A Vistor that will call the version method of the given CmdLineOutput + * for the specified CmdLine object and then exit. + */ +class VersionVisitor: public Visitor +{ + private: + /** + * Prevent accidental copying + */ + VersionVisitor(const VersionVisitor& rhs); + VersionVisitor& operator=(const VersionVisitor& rhs); + + protected: + + /** + * The CmdLine of interest. + */ + CmdLineInterface* _cmd; + + /** + * The output object. + */ + CmdLineOutput** _out; + + public: + + /** + * Constructor. + * \param cmd - The CmdLine the output is generated for. + * \param out - The type of output. + */ + VersionVisitor( CmdLineInterface* cmd, CmdLineOutput** out ) + : Visitor(), _cmd( cmd ), _out( out ) { } + + /** + * Calls the version method of the output object using the + * specified CmdLine. + */ + void visit() { + (*_out)->version(*_cmd); + throw ExitException(0); + } + +}; + +} + +#endif diff --git a/src/Menge/include/tclap/Visitor.h b/src/Menge/include/tclap/Visitor.h new file mode 100644 index 00000000..38ddcbdb --- /dev/null +++ b/src/Menge/include/tclap/Visitor.h @@ -0,0 +1,53 @@ + +/****************************************************************************** + * + * file: Visitor.h + * + * Copyright (c) 2003, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef TCLAP_VISITOR_H +#define TCLAP_VISITOR_H + +namespace TCLAP { + +/** + * A base class that defines the interface for visitors. + */ +class Visitor +{ + public: + + /** + * Constructor. Does nothing. + */ + Visitor() { } + + /** + * Destructor. Does nothing. + */ + virtual ~Visitor() { } + + /** + * Does nothing. Should be overridden by child. + */ + virtual void visit() { } +}; + +} + +#endif diff --git a/src/Menge/include/tclap/XorHandler.h b/src/Menge/include/tclap/XorHandler.h new file mode 100644 index 00000000..d9dfad31 --- /dev/null +++ b/src/Menge/include/tclap/XorHandler.h @@ -0,0 +1,166 @@ + +/****************************************************************************** + * + * file: XorHandler.h + * + * Copyright (c) 2003, Michael E. Smoot . + * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_XORHANDLER_H +#define TCLAP_XORHANDLER_H + +#include +#include +#include +#include +#include + +namespace TCLAP { + +/** + * This class handles lists of Arg's that are to be XOR'd on the command + * line. This is used by CmdLine and you shouldn't ever use it. + */ +class XorHandler +{ + protected: + + /** + * The list of of lists of Arg's to be or'd together. + */ + std::vector< std::vector > _orList; + + public: + + /** + * Constructor. Does nothing. + */ + XorHandler( ) : _orList(std::vector< std::vector >()) {} + + /** + * Add a list of Arg*'s that will be orred together. + * \param ors - list of Arg* that will be xor'd. + */ + void add( std::vector& ors ); + + /** + * Checks whether the specified Arg is in one of the xor lists and + * if it does match one, returns the size of the xor list that the + * Arg matched. If the Arg matches, then it also sets the rest of + * the Arg's in the list. You shouldn't use this. + * \param a - The Arg to be checked. + */ + int check( const Arg* a ); + + /** + * Returns the XOR specific short usage. + */ + std::string shortUsage(); + + /** + * Prints the XOR specific long usage. + * \param os - Stream to print to. + */ + void printLongUsage(std::ostream& os); + + /** + * Simply checks whether the Arg is contained in one of the arg + * lists. + * \param a - The Arg to be checked. + */ + bool contains( const Arg* a ); + + std::vector< std::vector >& getXorList(); + +}; + + +////////////////////////////////////////////////////////////////////// +//BEGIN XOR.cpp +////////////////////////////////////////////////////////////////////// +inline void XorHandler::add( std::vector& ors ) +{ + _orList.push_back( ors ); +} + +inline int XorHandler::check( const Arg* a ) +{ + // iterate over each XOR list + for ( int i = 0; static_cast(i) < _orList.size(); i++ ) + { + // if the XOR list contains the arg.. + ArgVectorIterator ait = std::find( _orList[i].begin(), + _orList[i].end(), a ); + if ( ait != _orList[i].end() ) + { + // first check to see if a mutually exclusive switch + // has not already been set + for ( ArgVectorIterator it = _orList[i].begin(); + it != _orList[i].end(); + it++ ) + if ( a != (*it) && (*it)->isSet() ) + throw(CmdLineParseException( + "Mutually exclusive argument already set!", + (*it)->toString())); + + // go through and set each arg that is not a + for ( ArgVectorIterator it = _orList[i].begin(); + it != _orList[i].end(); + it++ ) + if ( a != (*it) ) + (*it)->xorSet(); + + // return the number of required args that have now been set + if ( (*ait)->allowMore() ) + return 0; + else + return static_cast(_orList[i].size()); + } + } + + if ( a->isRequired() ) + return 1; + else + return 0; +} + +inline bool XorHandler::contains( const Arg* a ) +{ + for ( int i = 0; static_cast(i) < _orList.size(); i++ ) + for ( ArgVectorIterator it = _orList[i].begin(); + it != _orList[i].end(); + it++ ) + if ( a == (*it) ) + return true; + + return false; +} + +inline std::vector< std::vector >& XorHandler::getXorList() +{ + return _orList; +} + + + +////////////////////////////////////////////////////////////////////// +//END XOR.cpp +////////////////////////////////////////////////////////////////////// + +} //namespace TCLAP + +#endif diff --git a/src/Menge/include/tclap/ZshCompletionOutput.h b/src/Menge/include/tclap/ZshCompletionOutput.h new file mode 100644 index 00000000..0b37fc72 --- /dev/null +++ b/src/Menge/include/tclap/ZshCompletionOutput.h @@ -0,0 +1,323 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: ZshCompletionOutput.h + * + * Copyright (c) 2006, Oliver Kiddle + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H +#define TCLAP_ZSHCOMPLETIONOUTPUT_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace TCLAP { + +/** + * A class that generates a Zsh completion function as output from the usage() + * method for the given CmdLine and its Args. + */ +class ZshCompletionOutput : public CmdLineOutput +{ + + public: + + ZshCompletionOutput(); + + /** + * Prints the usage to stdout. Can be overridden to + * produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void usage(CmdLineInterface& c); + + /** + * Prints the version to stdout. Can be overridden + * to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + */ + virtual void version(CmdLineInterface& c); + + /** + * Prints (to stderr) an error message, short usage + * Can be overridden to produce alternative behavior. + * \param c - The CmdLine object the output is generated for. + * \param e - The ArgException that caused the failure. + */ + virtual void failure(CmdLineInterface& c, + ArgException& e ); + + protected: + + void basename( std::string& s ); + void quoteSpecialChars( std::string& s ); + + std::string getMutexList( CmdLineInterface& _cmd, Arg* a ); + void printOption( Arg* it, std::string mutex ); + void printArg( Arg* it ); + + std::map common; + char theDelimiter; +}; + +ZshCompletionOutput::ZshCompletionOutput() +: common(std::map()), + theDelimiter('=') +{ + common["host"] = "_hosts"; + common["hostname"] = "_hosts"; + common["file"] = "_files"; + common["filename"] = "_files"; + common["user"] = "_users"; + common["username"] = "_users"; + common["directory"] = "_directories"; + common["path"] = "_directories"; + common["url"] = "_urls"; +} + +inline void ZshCompletionOutput::version(CmdLineInterface& _cmd) +{ + std::cout << _cmd.getVersion() << std::endl; +} + +inline void ZshCompletionOutput::usage(CmdLineInterface& _cmd ) +{ + std::list argList = _cmd.getArgList(); + std::string progName = _cmd.getProgramName(); + std::string xversion = _cmd.getVersion(); + theDelimiter = _cmd.getDelimiter(); + basename(progName); + + std::cout << "#compdef " << progName << std::endl << std::endl << + "# " << progName << " version " << _cmd.getVersion() << std::endl << std::endl << + "_arguments -s -S"; + + for (ArgListIterator it = argList.begin(); it != argList.end(); it++) + { + if ( (*it)->shortID().at(0) == '<' ) + printArg((*it)); + else if ( (*it)->getFlag() != "-" ) + printOption((*it), getMutexList(_cmd, *it)); + } + + std::cout << std::endl; +} + +inline void ZshCompletionOutput::failure( CmdLineInterface& _cmd, + ArgException& e ) +{ + static_cast(_cmd); // unused + std::cout << e.what() << std::endl; +} + +inline void ZshCompletionOutput::quoteSpecialChars( std::string& s ) +{ + size_t idx = s.find_last_of(':'); + while ( idx != std::string::npos ) + { + s.insert(idx, 1, '\\'); + idx = s.find_last_of(':', idx); + } + idx = s.find_last_of('\''); + while ( idx != std::string::npos ) + { + s.insert(idx, "'\\'"); + if (idx == 0) + idx = std::string::npos; + else + idx = s.find_last_of('\'', --idx); + } +} + +inline void ZshCompletionOutput::basename( std::string& s ) +{ + size_t p = s.find_last_of('/'); + if ( p != std::string::npos ) + { + s.erase(0, p + 1); + } +} + +inline void ZshCompletionOutput::printArg(Arg* a) +{ + static int count = 1; + + std::cout << " \\" << std::endl << " '"; + if ( a->acceptsMultipleValues() ) + std::cout << '*'; + else + std::cout << count++; + std::cout << ':'; + if ( !a->isRequired() ) + std::cout << ':'; + + std::cout << a->getName() << ':'; + std::map::iterator compArg = common.find(a->getName()); + if ( compArg != common.end() ) + { + std::cout << compArg->second; + } + else + { + std::cout << "_guard \"^-*\" " << a->getName(); + } + std::cout << '\''; +} + +inline void ZshCompletionOutput::printOption(Arg* a, std::string mutex) +{ + std::string flag = a->flagStartChar() + a->getFlag(); + std::string name = a->nameStartString() + a->getName(); + std::string desc = a->getDescription(); + + // remove full stop and capitalisation from description as + // this is the convention for zsh function + if (!desc.compare(0, 12, "(required) ")) + { + desc.erase(0, 12); + } + if (!desc.compare(0, 15, "(OR required) ")) + { + desc.erase(0, 15); + } + size_t len = desc.length(); + if (len && desc.at(--len) == '.') + { + desc.erase(len); + } + if (len) + { + desc.replace(0, 1, 1, tolower(desc.at(0))); + } + + std::cout << " \\" << std::endl << " '" << mutex; + + if ( a->getFlag().empty() ) + { + std::cout << name; + } + else + { + std::cout << "'{" << flag << ',' << name << "}'"; + } + if ( theDelimiter == '=' && a->isValueRequired() ) + std::cout << "=-"; + quoteSpecialChars(desc); + std::cout << '[' << desc << ']'; + + if ( a->isValueRequired() ) + { + std::string arg = a->shortID(); + arg.erase(0, arg.find_last_of(theDelimiter) + 1); + if ( arg.at(arg.length()-1) == ']' ) + arg.erase(arg.length()-1); + if ( arg.at(arg.length()-1) == ']' ) + { + arg.erase(arg.length()-1); + } + if ( arg.at(0) == '<' ) + { + arg.erase(arg.length()-1); + arg.erase(0, 1); + } + size_t p = arg.find('|'); + if ( p != std::string::npos ) + { + do + { + arg.replace(p, 1, 1, ' '); + } + while ( (p = arg.find_first_of('|', p)) != std::string::npos ); + quoteSpecialChars(arg); + std::cout << ": :(" << arg << ')'; + } + else + { + std::cout << ':' << arg; + std::map::iterator compArg = common.find(arg); + if ( compArg != common.end() ) + { + std::cout << ':' << compArg->second; + } + } + } + + std::cout << '\''; +} + +inline std::string ZshCompletionOutput::getMutexList( CmdLineInterface& _cmd, Arg* a) +{ + XorHandler xorHandler = _cmd.getXorHandler(); + std::vector< std::vector > xorList = xorHandler.getXorList(); + + if (a->getName() == "help" || a->getName() == "version") + { + return "(-)"; + } + + std::ostringstream list; + if ( a->acceptsMultipleValues() ) + { + list << '*'; + } + + for ( int i = 0; static_cast(i) < xorList.size(); i++ ) + { + for ( ArgVectorIterator it = xorList[i].begin(); + it != xorList[i].end(); + it++) + if ( a == (*it) ) + { + list << '('; + for ( ArgVectorIterator iu = xorList[i].begin(); + iu != xorList[i].end(); + iu++ ) + { + bool notCur = (*iu) != a; + bool hasFlag = !(*iu)->getFlag().empty(); + if ( iu != xorList[i].begin() && (notCur || hasFlag) ) + list << ' '; + if (hasFlag) + list << (*iu)->flagStartChar() << (*iu)->getFlag() << ' '; + if ( notCur || hasFlag ) + list << (*iu)->nameStartString() << (*iu)->getName(); + } + list << ')'; + return list.str(); + } + } + + // wasn't found in xor list + if (!a->getFlag().empty()) { + list << "(" << a->flagStartChar() << a->getFlag() << ' ' << + a->nameStartString() << a->getName() << ')'; + } + + return list.str(); +} + +} //namespace TCLAP +#endif diff --git a/src/Menge/include/tinystr.h b/src/Menge/include/tinystr.h new file mode 100644 index 00000000..3c2aa9d5 --- /dev/null +++ b/src/Menge/include/tinystr.h @@ -0,0 +1,319 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. + * + * - completely rewritten. compact, clean, and fast implementation. + * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) + * - fixed reserve() to work as per specification. + * - fixed buggy compares operator==(), operator<(), and operator>() + * - fixed operator+=() to take a const ref argument, following spec. + * - added "copy" constructor with length, and most compare operators. + * - added swap(), clear(), size(), capacity(), operator+(). + */ + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/src/Menge/include/tinyxml.h b/src/Menge/include/tinyxml.h new file mode 100644 index 00000000..ee731739 --- /dev/null +++ b/src/Menge/include/tinyxml.h @@ -0,0 +1,1803 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#define TIXML_USE_STL + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 5; +const int TIXML_PATCH_VERSION = 3; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simple called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + const TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* Find( const char* _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + #ifdef TIXML_USE_STL + const TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* Find( const std::string& _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + + #endif + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + /* + This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" + but template specialization is hard to get working cross-compiler. Leaving the bug for now. + + // The above will fail for std::string because the space character is used as a seperator. + // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string + template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + */ + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && LoadFile( f.buffer, encoding )); + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && SaveFile( f.buffer )); + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/Menge/include/zlib.h b/src/Menge/include/zlib.h new file mode 100644 index 00000000..02281792 --- /dev/null +++ b/src/Menge/include/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/Menge/mengeMain/ProjectSpec.cpp b/src/Menge/mengeMain/ProjectSpec.cpp new file mode 100644 index 00000000..a068bf6b --- /dev/null +++ b/src/Menge/mengeMain/ProjectSpec.cpp @@ -0,0 +1,351 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ProjectSpec.h" +#include "tinyxml.h" +#include "SimulatorDB.h" +#include "tclap/CmdLine.h" +#include "os.h" + +//////////////////////////////////////////////////////////////// +// Implementation of ProjectSpec +//////////////////////////////////////////////////////////////// + +ProjectSpec::ProjectSpec() : _projPath("."), + _sceneXML(""), + _behaviorXML(""), + _modelName(""), + _scbFileName(""), + _scbVersion("2.1"), + _verbose(false), + _viewConfig(""), + _duration(400.f), + _timeStep(-1.f), + _seed(0), + _imgDumpPath(".") + { +} + +//////////////////////////////////////////////////////////////// + +ProjectSpec::~ProjectSpec() { +} + +//////////////////////////////////////////////////////////////// + +bool ProjectSpec::parseCommandParameters( int argc, char* argv[], const SimulatorDB * simDB ) { + bool valid = true; + // Command line argument fields + try { + TCLAP::CmdLine cmd("Crowd simulation with behavior. ", ' ', "0.9"); + // arguments: flag, name, description, required, default value type description + TCLAP::ValueArg< std::string > projArg( "p", "project", "The name of the project file", false, "", "string", cmd ); + TCLAP::ValueArg< std::string > sceneArg( "s", "scene", "Scene configuration file", false, "", "string", cmd ); + TCLAP::ValueArg< std::string > behaveArg( "b", "behavior", "Scene behavior file", false, "", "string", cmd ); + TCLAP::ValueArg< std::string > viewCfgArg( "", "view", "A view config file to specify the view - if this argument is specified, do not specify the -i/-interactive argument.", false, "", "string", cmd ); + TCLAP::ValueArg< std::string > outputArg( "o", "output", "Name of output file (Only writes output if file provided)", false, "", "string", cmd ); + TCLAP::ValueArg< std::string > versionArg( "", "scbVersion", "Version of scb file to write (1.0, 2.0, 2.1, 2.2, 2.3, or 2.4 -- 2.1 is the default", false, "2.1", "string", cmd ); + TCLAP::ValueArg< float > durationArg( "d", "duration", "Maximum duration of simulation (if final state is not achieved.) Defaults to 400 seconds.", false, -1.f, "float", cmd ); + TCLAP::ValueArg< float > timeStepArg( "t", "timeStep", "Override the time step in the scene specification with this one", false, -1.f, "float", cmd ); + TCLAP::SwitchArg silentArg( "", "verbose", "Make the simulator print loading and simulating progress", cmd, false ); + TCLAP::ValueArg< int > randomSeedArg( "r", "random", "Specify the global, default random seed. If not defined, or zero is given, the default seed will be extracted from the system clock every time a default seed is requested. Otherwise the constant value will be provided.", false, 0, "int", cmd ); + TCLAP::ValueArg< int > subSampleArg( "", "subSteps", "Specify the number of sub steps to take. If the simulation time step is 10 Hz with 1 substep, it actually runs at 20 Hz, but output is only updated at 10 Hz.", false, 0, "int", cmd ); + + std::string modelDoc = "The pedestrian model to use. Should be one of: "; + modelDoc += simDB->paramList(); + TCLAP::ValueArg< std::string > modelArg( "m", "model", modelDoc.c_str(), false, "", "string", cmd ); + TCLAP::SwitchArg listModelsArg( "l", "listModels", "Lists the models supported. If this is specified, no simulation is run.", cmd, false ); + TCLAP::SwitchArg listModelsFullArg( "L", "listModelsDetails", "Lists the models supported and provides more details. If this is specified, no simulation is run.", cmd, false ); + TCLAP::ValueArg< std::string > dumpPathArg( "u", "dumpPath", "The path to a folder in which screen grabs should be dumped. Defaults to current directory. (Will create the directory if it doesn't already exist.)", false, "", "string", cmd ); + + cmd.parse( argc, argv ); + + if ( listModelsFullArg.getValue() ) { + std::cout << "\n" << simDB->longDescriptions() << "\n"; + return false; + } + if ( listModelsArg.getValue() ) { + std::cout << "\n" << simDB->briefDescriptions() << "\n"; + return false; + } + + // Read the project file + std::string projName = projArg.getValue(); + if ( projName != "" ) { + if ( ! loadFromXML( projName ) ) { + return false; + } + } + + // Required arguments + std::string temp = sceneArg.getValue(); + if ( temp != "" ) { + std::string tmp = os::path::join( 2, ".", temp.c_str() ); + os::path::absPath( tmp, _sceneXML ); + } + if ( _sceneXML == "" ) { + std::cerr << "!!! To run a simulation, a scene specification must be provided (-s or --scene)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + temp = behaveArg.getValue(); + if ( temp != "" ) { + std::string tmp = os::path::join( 2, ".", temp.c_str() ); + os::path::absPath( tmp, _behaviorXML ); + } + if ( _behaviorXML == "" ) { + std::cerr << "!!! To run a simulation, a behavior specification must be provided (-b or --behavior)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + temp = modelArg.getValue(); + if ( temp != "" ) _modelName = temp; + if ( _modelName == "" ) { + std::cerr << "!!! To run a simulation, a named pedestrian model must be specified (-m or --model)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + // Optional arguments + _verbose = silentArg.getValue(); + + temp = outputArg.getValue(); + if ( temp != "" ) setOutputName( temp ); + + temp = versionArg.getValue(); + if ( temp != "" ) _scbVersion = temp; + + float f = timeStepArg.getValue(); + if ( f > 0.f ) _timeStep = f; + + f = durationArg.getValue(); + if ( f > 0.f ) _duration = f; + + int seed = randomSeedArg.getValue(); + if ( seed > -1 ) _seed = seed; + + temp = viewCfgArg.getValue(); + if ( temp != "" ) _viewConfig = temp; + + _subSteps = (size_t)subSampleArg.getValue(); + + + temp = dumpPathArg.getValue(); + if ( temp != "" ) { + std::string tmp = os::path::join( 2, ".", temp.c_str() ); + os::path::absPath( tmp, _imgDumpPath ); + } + + } catch ( TCLAP::ArgException &e ) { + std::cerr << "Error parsing command-line arguments: " << e.error() << " for arg " << e.argId() << std::endl; + } + + if ( _verbose ) { + logger << Logger::INFO_MSG << (*this) << "\n"; + } + return valid; +} + +//////////////////////////////////////////////////////////////// + +bool ProjectSpec::fullySpecified() const { + bool valid = true; + if ( _behaviorXML == "" ) { + std::cerr << "!!! To run a simulation, a behavior specification must be provided (-b or --behavior)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + if ( _sceneXML == "" ) { + std::cerr << "!!! To run a simulation, a scene specification must be provided (-s or --scene)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + + if ( _modelName == "" ) { + std::cerr << "!!! To run a simulation, a named pedestrian model must be specified (-m or --model)\n"; + std::cerr << " or defined in the project file.\n"; + valid = false; + } + + return valid; +} + +//////////////////////////////////////////////////////////////// + +void ProjectSpec::setOutputName( const std::string & fileName ) { + os::path::absPath( fileName, _scbFileName ); + if ( _scbFileName != "" ) { + size_t nameLen = _scbFileName.size(); + if ( _scbFileName[ nameLen - 1 ] != 'b' || + _scbFileName[ nameLen - 2 ] != 'c' || + _scbFileName[ nameLen - 3 ] != 's' || + _scbFileName[ nameLen - 4 ] != '.' ) { + _scbFileName += ".scb"; + } + } +} + +//////////////////////////////////////////////////////////////// + +bool ProjectSpec::loadFromXML( const std::string & xmlName ) { + // TODO: Extract the project path from xmlName. path, file = os.path.split( os.path.absPath( xmlName ) ) + TiXmlDocument xml( xmlName ); + bool valid = xml.LoadFile(); + + if ( !valid ) { // load xml file + std::cerr << "Could not load project specification xml " << xmlName << ".\n"; + return false; + } + + TiXmlElement* rootNode = xml.RootElement(); + if( ! rootNode ) { + std::cerr << "Root element does not exist\n."; + return false; + } + + if( rootNode->ValueStr () != "Project" ) { + std::cerr << "Root element value is not 'Project'.\n" ; + return false; + } + + std::string absPath; + os::path::absPath( xmlName, absPath ); + std::string junk; + os::path::split( absPath, _projPath, junk ); + logger.line(); + logger << Logger::INFO_MSG << "Project root: " << _projPath << "\n"; + + // Project parameters + { + const char * name = rootNode->Attribute( "scene" ); + if ( name != 0x0 ) { + std::string tmp = os::path::join( 2, _projPath.c_str(), name ); + os::path::absPath( tmp, _sceneXML ); + } + } + + { + const char * name = rootNode->Attribute( "behavior" ); + if ( name != 0x0 ) { + std::string tmp = os::path::join( 2, _projPath.c_str(), name ); + os::path::absPath( tmp, _behaviorXML ); + } + } + + { + const char * name = rootNode->Attribute( "model" ); + if ( name != 0x0 ) { + _modelName = std::string( name ); + } + } + + { + const char * name = rootNode->Attribute( "output" ); + if ( name != 0x0 ) { + setOutputName( os::path::join( 2, _projPath.c_str(), name ) ); + } + } + + { + const char * name = rootNode->Attribute( "scbVersion" ); + if ( name != 0x0 ) { + // TODO: Validate this version + _scbVersion = std::string( name ); + } + } + + { + const char * name = rootNode->Attribute( "dumpPath" ); + if ( name != 0x0 ) { + std::string tmp = os::path::join( 2, _projPath.c_str(), name ); + os::path::absPath( tmp, _imgDumpPath ); + } + } + + { + const char * name = rootNode->Attribute( "view" ); + if ( name != 0x0 ) { + std::string tmp = os::path::join( 2, _projPath.c_str(), name ); + os::path::absPath( tmp, _viewConfig ); + } + } + + double d; + int i; + + if ( rootNode->Attribute( "duration", &d ) ) { + _duration = (float)d; + } + + if ( rootNode->Attribute( "timeStep", &d ) ) { + _timeStep = (float)d; + } + + if ( rootNode->Attribute( "random", &i ) ) { + _seed = i; + } + + if ( rootNode->Attribute( "subSteps", &i ) ) { + _subSteps = (size_t)i; + } + + return true; +} + +//////////////////////////////////////////////////////////////// + +Logger & operator<<( Logger & out, const ProjectSpec & spec ) { + out << "\n\n"; + return out; +} \ No newline at end of file diff --git a/src/Menge/mengeMain/ProjectSpec.h b/src/Menge/mengeMain/ProjectSpec.h new file mode 100644 index 00000000..fcbac201 --- /dev/null +++ b/src/Menge/mengeMain/ProjectSpec.h @@ -0,0 +1,306 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ProjectSpec.h + * @brief The definition of the parameters required to run a simulation. + */ + +#ifndef __PROJECT_SPEC_H__ +#define __PROJECT_SPEC_H__ + +#include +#include +#include "Logger.h" + +using namespace Menge; + +// Forward declaration +namespace Menge { + class SimulatorDB; +} + +/*! + * @brief The specificaiton of a simulation project. + * + * Some project parameters have default values (such as duration and random seed). + * Others require explicit definitions (such as scene specification, etc.) + * The break down is as follows: + * + * Required parameters: + * - Scene specification + * - Behavior specification + * - Model name + * + * Optional parameters (with defaults): + * - Interactive flag (false) + * - View specification (None -- no interactive view if interactive flag is false) + * - Output trajectory file name (None -- no output) + * - Trajectory version (2.1) + * - Simulation duration limit (400 s) + * - Simulation time step (use time step in scene specification) + * - Display verbose progress (false) + * - Random seed argument (0) + */ +class ProjectSpec { +public: + /*! + * @brief Constructor + */ + ProjectSpec(); + + + /*! + * @brief Destructor + */ + ~ProjectSpec(); + + /*! + * @brief Get the scene specification file name + * + * @returns The path to the scene specification file. + */ + std::string getScene() const { return _sceneXML; } + + /*! + * @brief Get the beahvior specification file name + * + * @returns The path to the behavior specification file. + */ + std::string getBehavior() const { return _behaviorXML; } + + /*! + * @brief Get the model name + * + * @returns The path to the string specification file. + */ + std::string getModel() const { return _modelName; } + + /*! + * @brief Get the name of the trajectory output file. + * + * @returns The name of the output file. Empty string if no + * output file is to be written. + */ + std::string getOutputName() const { return _scbFileName; } + + /*! + * @brief Get the version string for the trajectory output file. + * + * @returns The version of the output file to write. + */ + std::string getSCBVersion() const { return _scbVersion; } + + /*! + * @brief Get the verbosity state for the application + * + * @returns True if the application should be verbose, false otherwise. + */ + bool getVerbosity() const { return _verbose; } + + /*! + * @brief Get the view specification file. + * + * @returns The name of the view configuration file (empty string if + * there is none). + */ + std::string getView() const { return _viewConfig; } + + /*! + * @brief Get the random number seed value + * + * @returns The global random number generator seed. + */ + int getRandomSeed() const { return _seed; } + + /*! + * @brief Get the path at which to dump files. + * + * @returns The folder in which screen captures should be written. + */ + std::string getDumpPath() const { return _imgDumpPath; } + + /*! + * @brief Get the number of simulation sub steps to take. + * + * @returns The number of simulation sub steps. + */ + size_t getSubSteps() const { return _subSteps; } + + /*! + * @brief Get the maximum simulation duration + * + * @returns The maximum allowable simulation duration. + */ + float getDuration() const { return _duration; } + + /*! + * @brief Get the override simulation time step + * + * @returns The overridden simulation time step. If negative, + * use the time step in the scene specification. + */ + float getTimeStep() const { return _timeStep; } + + /*! + * @brief Parse the command line arguments + * + * @param argc the number of command-line arguments. + * @param argv The command-line parameters. + * @param simDB A pointer to the current simulator database. + * @returns True if a simulation should be attempted (i.e. the + * project specification and command-line parameters require it + * and false if not. + */ + bool parseCommandParameters( int argc, char* argv[], const SimulatorDB * simDB ); + + /*! + * @brief Reports if the project specification contains enough information + * to attempt to run a simulation. I.e., it has *values* for all + * fields but does not know if those values are valid. + * + * @returns True if all required fields have values, false otherwise. + */ + bool fullySpecified() const; + + /*! + * @brief Print the project specification to an output stream. + * + * @param out An output stream. + * @param spec A ProjectSpec + * @returns A reference to the output stream + */ + friend Logger & operator<<( Logger & out, const ProjectSpec & spec ); + +protected: + /*! + * @brief Set output file + * + * @param fileName The name of the file to write the trajectories to. + */ + void setOutputName( const std::string & fileName ); + + /*! + * @brief Loads a project specification from an xml file + * + * The return value only indicates if there was successful parsing of the xml. + * It does not imply that there was sufficient information in the project to + * run a simulation. Ultimately, a successful project is defined by the union + * of the project file and the command-line parameters. + * + * @param xmlName The path to the file containing the project specification. + * @returns True if parsing was successful, false otherwise. + */ + bool loadFromXML( const std::string & xmlName ); + + /*! + * @brief The path to the project -- it is the folder containing the + * project xml. Defaults to the current working directory. + */ + std::string _projPath; + + /*! + * @brief The full path to the scene specification xml file. + */ + std::string _sceneXML; + + /*! + * @brief The full path to the behavior specification xml file. + */ + std::string _behaviorXML; + + /*! + * @brief The name of the pedestrian model. + */ + std::string _modelName; + + /*! + * @brief The name of the output trajectory file to write. + */ + std::string _scbFileName; + + /*! + * @brief The scb version to write. + */ + std::string _scbVersion; + + /*! + * @brief Determines if the simulator should be verbose (printing status + * to the console. + */ + bool _verbose; + + /*! + * @brief The path to the file that specifies the view configuration. + */ + std::string _viewConfig; + + /*! + * @brief The maximum allowable duration of the simulation (in simulation seconds). + */ + float _duration; + + /*! + * @brief The size of the simulation time step. + */ + float _timeStep; + + /*! + * @brief The seed number for the global random number generator. + */ + int _seed; + + /*! + * @brief The path to the output folder for screen grab images + */ + std::string _imgDumpPath; + + /*! + * @brief The number of intermediate simulation steps to take. + * + * If the simulation time step is N Hz, and substeps is set to + * k, then the effective simulation rate is N * ( 1 + k ) Hz. + * For example, simulate at 10 Hz, with a single substep. + * Simulation is performed at 10 * (1 + 1) = 20 Hz, but the + * results are only output at 10 Hz. + */ + size_t _subSteps; + +}; + +#endif // __PROJECT_SPEC_H__ diff --git a/src/Menge/mengeMain/common.h b/src/Menge/mengeMain/common.h new file mode 100644 index 00000000..a8d1aaa2 --- /dev/null +++ b/src/Menge/mengeMain/common.h @@ -0,0 +1,59 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file common.h + * @brief A set of common includes for the main application. + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#ifdef _WIN32 +#include +#endif +#include "GL/gl.h" +#include +#include +#include "macros.h" +#include "math/vector.h" +#include "math/consts.h" +#include "math/Matrix.h" +using namespace Math; + +#endif // __COMMON_H__ \ No newline at end of file diff --git a/src/Menge/mengeMain/mengeMain.cpp b/src/Menge/mengeMain/mengeMain.cpp new file mode 100644 index 00000000..e4c4ef34 --- /dev/null +++ b/src/Menge/mengeMain/mengeMain.cpp @@ -0,0 +1,244 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +// STL +#include +#include +#include +#include + +// UTILS +#include "ProjectSpec.h" +// Command-line parser +#include "tclap/CmdLine.h" +// Visualization +#include "GLScene.h" +#include "GLViewer.h" +#include "ViewConfig.h" +#include "NullViewer.h" +#include "ContextSwitcher.h" +// Menge Runtime +#include "SimSystem.h" +#include "PluginEngine.h" +#include "SimulatorDB.h" +#include "os.h" +#include "BaseAgentContext.h" +#include "Logger.h" +// SceneGraph +#include "TextWriter.h" +// Menge Math +#include "RandGenerator.h" + +using namespace Menge; + +// Time step (gets set by the scene.xml file +float TIME_STEP = 0.2f; +// The number of uniform simulation steps to take between logical time steps +size_t SUB_STEPS = 0; + +// Maximum duration of simulation (in seconds) +// Can be set on command line. +float SIM_DURATION = 800.f; + +// Controls whether the simulation is verbose or not +bool VERBOSE = false; + +// The location of the executable - for basic executable resources +std::string ROOT; + +SimulatorDB simDB; + +/*! + * @brief Initialize and start the simulation. + * + * @param dbEntry The SimulatorDBEntry that describes the simulator + * to be instantiated. + * @param behaveFile The path to a valid behavior specification file. + * @param sceneFile The path to a valid scene specification file. + * @param outFile The path to the output file to write. If it is the + * empty string, no output file will be written. + * @param scbVersion The string indicating the version of scb file to write. + * @param visualize Determines if the simulation should be visualized. + * If true, an OpenGL visualizer is spawned, if false + * the simulation runs offline. + * @param viewCfgFile If visualizing, a path to an optional view configuration + * specification. If none is provided, defaults are used. + * @param dumpPath The path to write screen grabs. Only used in windows. + * @returns 0 for a successful run, non-zero otherwise. + */ +int simMain( SimulatorDBEntry * dbEntry, const std::string & behaveFile, const std::string & sceneFile, const std::string & outFile, const std::string & scbVersion, bool visualize, const std::string & viewCfgFile, const std::string & dumpPath ) { + size_t agentCount; + if ( outFile != "" ) logger << Logger::INFO_MSG << "Attempting to write scb file: " << outFile << "\n"; + SimSystem * system = dbEntry->getSimulatorSystem( agentCount, TIME_STEP, SUB_STEPS, SIM_DURATION, behaveFile, sceneFile, outFile, scbVersion, visualize, VERBOSE ); + + if ( system == 0x0 ) { + return 1; + } + + SceneGraph::GLScene * scene = new SceneGraph::GLScene(); + scene->addSystem( system ); + + if ( visualize ) { + Vis::ViewConfig viewCfg; + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "Using visualizer!"; + } + if ( viewCfgFile == "" ) { + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "\tUsing default visualization settings."; + } + } else { + // TODO: Error handling + if ( viewCfg.readXML( viewCfgFile ) ) { + if ( VERBOSE ) { + logger << Logger::INFO_MSG << "\tUsing visualization from: " << viewCfgFile << "\n"; + logger << Logger::INFO_MSG << viewCfg << "\n"; + } + } else { + logger << Logger::ERR_MSG << "Unable to read the specified view configuration (" << viewCfgFile << "). Terminating."; + return 1; + } + } + Vis::GLViewer view( viewCfg ); + + view.setDumpPath( dumpPath ); + +#ifdef NDEBUG + std::string viewTitle = "Pedestrian Simulation - " + dbEntry->viewerName(); +#else + std::string viewTitle = "(DEBUG) Pedestrian Simulation - " + dbEntry->viewerName(); +#endif + if ( !view.initViewer( viewTitle ) ) { + std::cerr << "Unable to initialize the viewer\n\n"; + visualize = false; + } else { + view.setScene( scene ); + view.setFixedStep( TIME_STEP ); + view.setBGColor( 0.1f, 0.1f, 0.1f ); + dbEntry->populateScene( system, scene ); + SceneGraph::ContextSwitcher * switcher = new SceneGraph::ContextSwitcher(); + SceneGraph::Context * ctx = dbEntry->getAgentContext( system ); + switcher->addContext( ctx, SDLK_a ); + scene->setContext( switcher ); + view.newGLContext(); + logger.line(); + + view.run(); + logger << Logger::INFO_MSG << "Simulation time: " << dbEntry->simDuration() << "\n"; + } + } else { + logger << Logger::INFO_MSG << "NO VISUALIZATION!\n"; + Vis::NullViewer view; // need the call back + view.setScene( scene ); + view.setFixedStep( TIME_STEP ); + logger.line(); + + view.run(); + std::cout << "Simulation time: " << dbEntry->simDuration() << "\n"; + logger << Logger::INFO_MSG << "Simulation time: " << dbEntry->simDuration() << "\n"; + } + + return 0; +} + +int main(int argc, char* argv[]) { + logger.setFile( "log.html" ); + logger << Logger::INFO_MSG << "initialized logger"; + + std::string exePath( argv[0] ); + std::string absExePath; + os::path::absPath( exePath, absExePath ); + std::string tail; + os::path::split( absExePath, ROOT, tail ); + PluginEngine plugins( &simDB ); +#ifdef _WIN32 + #ifdef NDEBUG + std::string pluginPath = os::path::join( 2, ROOT.c_str(), "plugins" ); + #else // NDEBUG + std::string pluginPath = os::path::join( 3, ROOT.c_str(), "plugins", "debug" ); + #endif // NDEBUG +#else // _WIN32 + std::string pluginPath = os::path::join( 2, ROOT.c_str(), "plugins" ); +#endif // _WIN32 + logger.line(); + logger << Logger::INFO_MSG << "Plugin path: " << pluginPath; + plugins.loadPlugins( pluginPath ); + if ( simDB.modelCount() == 0 ) { + logger << Logger::INFO_MSG << "There were no pedestrian models in the plugins folder\n"; + return 1; + } + + SceneGraph::TextWriter::setDefaultFont( os::path::join( 2, ROOT.c_str(), "arial.ttf" ) ); + ProjectSpec projSpec; + + if (! projSpec.parseCommandParameters( argc, argv, &simDB ) ) { + return 0; + } + + if ( !projSpec.fullySpecified() ) { + return 1; + } + + VERBOSE = projSpec.getVerbosity(); + TIME_STEP = projSpec.getTimeStep(); + SUB_STEPS = projSpec.getSubSteps(); + SIM_DURATION = projSpec.getDuration(); + std::string dumpPath = projSpec.getDumpPath(); + setDefaultGeneratorSeed( projSpec.getRandomSeed() ); + std::string outFile = projSpec.getOutputName(); + + std::string viewCfgFile = projSpec.getView(); + bool useVis = viewCfgFile != ""; + std::string model( projSpec.getModel() ); + + SimulatorDBEntry * simDBEntry = simDB.getDBEntry( model ); + if ( simDBEntry == 0x0 ) { + std::cerr << "!!! The specified model is not recognized: " << model << "\n"; + logger.close(); + return 1; + } + + int result = simMain( simDBEntry, projSpec.getBehavior(), projSpec.getScene(), projSpec.getOutputName(), projSpec.getSCBVersion(), useVis, viewCfgFile, dumpPath ); + + if ( result ) { + std::cerr << "Simulation terminated through error. See error log for details.\n"; + } + logger.close(); + return result; +} + diff --git a/src/Menge/tinyxml/tinystr.cpp b/src/Menge/tinyxml/tinystr.cpp new file mode 100644 index 00000000..68125071 --- /dev/null +++ b/src/Menge/tinyxml/tinystr.cpp @@ -0,0 +1,116 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. + */ + + +#ifndef TIXML_USE_STL + +#include "tinystr.h" + +// Error value for find primitive +const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); + + +// Null rep. +TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; + + +void TiXmlString::reserve (size_type cap) +{ + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } +} + + +TiXmlString& TiXmlString::assign(const char* str, size_type len) +{ + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; +} + + +TiXmlString& TiXmlString::append(const char* str, size_type len) +{ + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; +} + + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) +{ + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; +} + +TiXmlString operator + (const TiXmlString & a, const char* b) +{ + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; +} + +TiXmlString operator + (const char* a, const TiXmlString & b) +{ + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; +} + + +#endif // TIXML_USE_STL diff --git a/src/Menge/tinyxml/tinystr.h b/src/Menge/tinyxml/tinystr.h new file mode 100644 index 00000000..3c2aa9d5 --- /dev/null +++ b/src/Menge/tinyxml/tinystr.h @@ -0,0 +1,319 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. + * + * - completely rewritten. compact, clean, and fast implementation. + * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) + * - fixed reserve() to work as per specification. + * - fixed buggy compares operator==(), operator<(), and operator>() + * - fixed operator+=() to take a const ref argument, following spec. + * - added "copy" constructor with length, and most compare operators. + * - added swap(), clear(), size(), capacity(), operator+(). + */ + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/src/Menge/tinyxml/tinyxml.cpp b/src/Menge/tinyxml/tinyxml.cpp new file mode 100644 index 00000000..5de21f6d --- /dev/null +++ b/src/Menge/tinyxml/tinyxml.cpp @@ -0,0 +1,1888 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include + +#ifdef TIXML_USE_STL +#include +#include +#endif + +#include "tinyxml.h" + + +bool TiXmlBase::condenseWhiteSpace = true; + +// Microsoft compiler security +FILE* TiXmlFOpen( const char* filename, const char* mode ) +{ + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + FILE* fp = 0; + errno_t err = fopen_s( &fp, filename, mode ); + if ( !err && fp ) + return fp; + return 0; + #else + return fopen( filename, mode ); + #endif +} + +void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + + if ( node->Type() == TiXmlNode::DOCUMENT ) + { + delete node; + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + + +const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + #else + TiXmlAttribute* node = attributeSet.Find( name ); + #endif + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +const TiXmlElement* TiXmlNode::FirstChildElement() const +{ + const TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + const TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +void TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char* TiXmlElement::Attribute( const char* name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return node->Value(); + return 0; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return &node->ValueStr(); + return 0; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, int* i ) const +{ + const char* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s ); + } + else { + *i = 0; + } + } + return s; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const +{ + const std::string* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s->c_str() ); + } + else { + *i = 0; + } + } + return s; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, double* d ) const +{ + const char* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s ); + } + else { + *d = 0; + } + } + return s; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const +{ + const std::string* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s->c_str() ); + } + else { + *d = 0; + } + } + return s; +} +#endif + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); +} +#endif + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); +} +#endif + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + char buf[64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); + #else + sprintf( buf, "%d", val ); + #endif + SetAttribute( name, buf ); +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, int val ) +{ + std::ostringstream oss; + oss << val; + SetAttribute( name, oss.str() ); +} +#endif + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + char buf[256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); + #else + sprintf( buf, "%f", val ); + #endif + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING _name( cname ); + TIXML_STRING _value( cvalue ); + #else + const char* _name = cname; + const char* _value = cvalue; + #endif + + TiXmlAttribute* node = attributeSet.Find( _name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} +#endif + + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + assert( cfile ); + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + +bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, attributeSet.First() ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +const char* TiXmlElement::GetText() const +{ + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + // See STL_STRING_BUG below. + //StringToBuffer buf( value ); + + return LoadFile( Value(), encoding ); +} + + +bool TiXmlDocument::SaveFile() const +{ + // See STL_STRING_BUG below. +// StringToBuffer buf( value ); +// +// if ( buf.buffer && SaveFile( buf.buffer ) ) +// return true; +// +// return false; + return SaveFile( Value() ); +} + +bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) +{ + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the std::string to + // be called. What is strange, is that the std::string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // Add an extra string to avoid the crash. + TIXML_STRING filename( _filename ); + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = TiXmlFOpen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } +} + +bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) +{ + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length <= 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + delete [] buf; + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + const char* lastPos = buf; + const char* p = buf; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + if ( *p == 0xa ) { + // Newline character. No special rules for this. Append all the characters + // since the last string, and include the newline. + data.append( lastPos, (p-lastPos+1) ); // append, include the newline + ++p; // move past the newline + lastPos = p; // and point to the new buffer (may be 0) + assert( p <= (buf+length) ); + } + else if ( *p == 0xd ) { + // Carriage return. Append what we have so far, then + // handle moving forward in the buffer. + if ( (p-lastPos) > 0 ) { + data.append( lastPos, p-lastPos ); // do not add the CR + } + data += (char)0xa; // a proper newline + + if ( *(p+1) == 0xa ) { + // Carriage return - new line sequence + p += 2; + lastPos = p; + assert( p <= (buf+length) ); + } + else { + // it was followed by something else...that is presumably characters again. + ++p; + lastPos = p; + assert( p <= (buf+length) ); + } + } + else { + ++p; + } + } + // Handle any left over characters. + if ( p-lastPos ) { + data.append( lastPos, p-lastPos ); + } + delete [] buf; + buf = 0; + + Parse( data.c_str(), 0, encoding ); + + if ( Error() ) + return false; + else + return true; +} + + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = TiXmlFOpen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; +} + + +bool TiXmlDocument::SaveFile( FILE* fp ) const +{ + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return (ferror(fp) == 0); +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorId = errorId; + target->errorDesc = errorDesc; + target->tabsize = tabsize; + target->errorLocation = errorLocation; + target->useMicrosoftBOM = useMicrosoftBOM; + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + + +bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +const TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +/* +TiXmlAttribute* TiXmlAttribute::Next() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} +*/ + +const TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +/* +TiXmlAttribute* TiXmlAttribute::Previous() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} +*/ + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + TIXML_STRING n, v; + + EncodeString( name, &n ); + EncodeString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) { + if ( cfile ) { + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; + } + } + else { + if ( cfile ) { + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; + } + } +} + + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); + #else + sprintf (buf, "%lf", _value); + #endif + SetValue (buf); +} + +int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i\n", value.c_str() ); // unformatted output + } + else + { + TIXML_STRING buffer; + EncodeString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); + target->cdata = cdata; +} + + +bool TiXmlText::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + if ( cfile ) fprintf( cfile, "" ); + if ( str ) (*str) += "?>"; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + #ifdef TIXML_USE_STL + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + #else + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + #endif + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + + +#ifdef TIXML_USE_STL +const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const +{ + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +/* +TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} +*/ +#endif + + +const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const +{ + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} + +/* +TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} +*/ + +#ifdef TIXML_USE_STL +std::istream& operator>> (std::istream & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +#ifdef TIXML_USE_STL +std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out << printer.Str(); + + return out; +} + + +std::string& operator<< (std::string& out, const TiXmlNode& base ) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out.append( printer.Str() ); + + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) +{ + DoIndent(); + buffer += "<"; + buffer += element.Value(); + + for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) + { + buffer += " "; + attrib->Print( 0, 0, &buffer ); + } + + if ( !element.FirstChild() ) + { + buffer += " />"; + DoLineBreak(); + } + else + { + buffer += ">"; + if ( element.FirstChild()->ToText() + && element.LastChild() == element.FirstChild() + && element.FirstChild()->ToText()->CDATA() == false ) + { + simpleTextPrint = true; + // no DoLineBreak()! + } + else + { + DoLineBreak(); + } + } + ++depth; + return true; +} + + +bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) +{ + --depth; + if ( !element.FirstChild() ) + { + // nothing. + } + else + { + if ( simpleTextPrint ) + { + simpleTextPrint = false; + } + else + { + DoIndent(); + } + buffer += ""; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlText& text ) +{ + if ( text.CDATA() ) + { + DoIndent(); + buffer += ""; + DoLineBreak(); + } + else if ( simpleTextPrint ) + { + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + } + else + { + DoIndent(); + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) +{ + DoIndent(); + declaration.Print( 0, 0, &buffer ); + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlComment& comment ) +{ + DoIndent(); + buffer += ""; + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) +{ + DoIndent(); + buffer += "<"; + buffer += unknown.Value(); + buffer += ">"; + DoLineBreak(); + return true; +} + diff --git a/src/Menge/tinyxml/tinyxml.h b/src/Menge/tinyxml/tinyxml.h new file mode 100644 index 00000000..ee731739 --- /dev/null +++ b/src/Menge/tinyxml/tinyxml.h @@ -0,0 +1,1803 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#define TIXML_USE_STL + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 5; +const int TIXML_PATCH_VERSION = 3; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simple called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + const TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* Find( const char* _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + #ifdef TIXML_USE_STL + const TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* Find( const std::string& _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + + #endif + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + /* + This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" + but template specialization is hard to get working cross-compiler. Leaving the bug for now. + + // The above will fail for std::string because the space character is used as a seperator. + // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string + template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + */ + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && LoadFile( f.buffer, encoding )); + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && SaveFile( f.buffer )); + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i +#include + +#include "tinyxml.h" + +//#define DEBUG_PARSER +#if defined( DEBUG_PARSER ) +# if defined( DEBUG ) && defined( _MSC_VER ) +# include +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif +#endif + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + +const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The +// "assign" optimization removes over 10% of the execution time. +// +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + // Oddly, not supported on some comilers, + //name->clear(); + // So use this: + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + const char* start = p; + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + //(*name) += *p; // expensive + ++p; + } + if ( p-start > 0 ) { + name->assign( start, p-start ); + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + if ( p ) + p += strlen( endTag ); + return p; +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocument* doc = GetDocument(); + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // [ 1475201 ] TinyXML parses entities in comments + // Oops - ReadText doesn't work, because we don't want to parse the entities. + // p = ReadText( p, &value, false, endTag, false, encoding ); + // + // from the XML spec: + /* + [Definition: Comments may appear anywhere in a document outside other markup; in addition, + they may appear within the document type declaration at places allowed by the grammar. + They are not part of the document's character data; an XML processor MAY, but need not, + make it possible for an application to retrieve the text of comments. For compatibility, + the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity + references MUST NOT be recognized within comments. + + An example of a comment: + + + */ + + value = ""; + // Keep all the white space. + while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) + { + value.append( p, 1 ); + ++p; + } + if ( p ) + p += strlen( endTag ); + + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + +// int tabsize = 4; +// if ( document ) +// tabsize = document->TabSize(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + const char SINGLE_QUOTE = '\''; + const char DOUBLE_QUOTE = '\"'; + + if ( *p == SINGLE_QUOTE ) + { + ++p; + end = "\'"; // single quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == DOUBLE_QUOTE ) + { + ++p; + end = "\""; // double quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { + // [ 1451649 ] Attribute values with trailing quotes not handled correctly + // We did not have an opening quote but seem to have a + // closing one. Give up and throw an error. + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( !cdata && (c == '<' ) ) + { + return; + } + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); // "commits" the peek made above + + if ( cdata && c == '>' && tag->size() >= 3 ) { + size_t len = tag->size(); + if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { + // terminator of cdata. + return; + } + } + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = ""; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; + } +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i + #include + using namespace std; +#else + #include +#endif + +#if defined( WIN32 ) && defined( TUNE ) + #include + _CrtMemState startMemState; + _CrtMemState endMemState; +#endif + +#include "tinyxml.h" + +static int gPass = 0; +static int gFail = 0; + + +bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false) +{ + bool pass = !strcmp( expected, found ); + if ( pass ) + printf ("[pass]"); + else + printf ("[fail]"); + + if ( noEcho ) + printf (" %s\n", testString); + else + printf (" %s [%s][%s]\n", testString, expected, found); + + if ( pass ) + ++gPass; + else + ++gFail; + return pass; +} + + +bool XmlTest( const char* testString, int expected, int found, bool noEcho = false ) +{ + bool pass = ( expected == found ); + if ( pass ) + printf ("[pass]"); + else + printf ("[fail]"); + + if ( noEcho ) + printf (" %s\n", testString); + else + printf (" %s [%d][%d]\n", testString, expected, found); + + if ( pass ) + ++gPass; + else + ++gFail; + return pass; +} + + +// +// This file demonstrates some basic functionality of TinyXml. +// Note that the example is very contrived. It presumes you know +// what is in the XML file. But it does test the basic operations, +// and show how to add and remove nodes. +// + +int main() +{ + // + // We start with the 'demoStart' todo list. Process it. And + // should hopefully end up with the todo list as illustrated. + // + const char* demoStart = + "\n" + "" + "\n" + "\n" + " Go to the Toy store!" + " Do bills " + " Look for Evil Dinosaurs! " + ""; + + { + + #ifdef TIXML_USE_STL + /* What the todo list should look like after processing. + In stream (no formatting) representation. */ + const char* demoEnd = + "" + "" + "" + "" + "Go to the" + "Toy store!" + "" + "" + "Talk to:" + "" + "" + "" + "" + "" + "" + "Do bills" + "" + ""; + #endif + + // The example parses from the character string (above): + #if defined( WIN32 ) && defined( TUNE ) + _CrtMemCheckpoint( &startMemState ); + #endif + + { + // Write to a file and read it back, to check file I/O. + + TiXmlDocument doc( "demotest.xml" ); + doc.Parse( demoStart ); + + if ( doc.Error() ) + { + printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() ); + exit( 1 ); + } + doc.SaveFile(); + } + + TiXmlDocument doc( "demotest.xml" ); + bool loadOkay = doc.LoadFile(); + + if ( !loadOkay ) + { + printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() ); + exit( 1 ); + } + + printf( "** Demo doc read from disk: ** \n\n" ); + printf( "** Printing via doc.Print **\n" ); + doc.Print( stdout ); + + { + printf( "** Printing via TiXmlPrinter **\n" ); + TiXmlPrinter printer; + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + } + #ifdef TIXML_USE_STL + { + printf( "** Printing via operator<< **\n" ); + std::cout << doc; + } + #endif + TiXmlNode* node = 0; + TiXmlElement* todoElement = 0; + TiXmlElement* itemElement = 0; + + + // -------------------------------------------------------- + // An example of changing existing attributes, and removing + // an element from the document. + // -------------------------------------------------------- + + // Get the "ToDo" element. + // It is a child of the document, and can be selected by name. + node = doc.FirstChild( "ToDo" ); + assert( node ); + todoElement = node->ToElement(); + assert( todoElement ); + + // Going to the toy store is now our second priority... + // So set the "priority" attribute of the first item in the list. + node = todoElement->FirstChildElement(); // This skips the "PDA" comment. + assert( node ); + itemElement = node->ToElement(); + assert( itemElement ); + itemElement->SetAttribute( "priority", 2 ); + + // Change the distance to "doing bills" from + // "none" to "here". It's the next sibling element. + itemElement = itemElement->NextSiblingElement(); + assert( itemElement ); + itemElement->SetAttribute( "distance", "here" ); + + // Remove the "Look for Evil Dinosaurs!" item. + // It is 1 more sibling away. We ask the parent to remove + // a particular child. + itemElement = itemElement->NextSiblingElement(); + todoElement->RemoveChild( itemElement ); + + itemElement = 0; + + // -------------------------------------------------------- + // What follows is an example of created elements and text + // nodes and adding them to the document. + // -------------------------------------------------------- + + // Add some meetings. + TiXmlElement item( "Item" ); + item.SetAttribute( "priority", "1" ); + item.SetAttribute( "distance", "far" ); + + TiXmlText text( "Talk to:" ); + + TiXmlElement meeting1( "Meeting" ); + meeting1.SetAttribute( "where", "School" ); + + TiXmlElement meeting2( "Meeting" ); + meeting2.SetAttribute( "where", "Lunch" ); + + TiXmlElement attendee1( "Attendee" ); + attendee1.SetAttribute( "name", "Marple" ); + attendee1.SetAttribute( "position", "teacher" ); + + TiXmlElement attendee2( "Attendee" ); + attendee2.SetAttribute( "name", "Voel" ); + attendee2.SetAttribute( "position", "counselor" ); + + // Assemble the nodes we've created: + meeting1.InsertEndChild( attendee1 ); + meeting1.InsertEndChild( attendee2 ); + + item.InsertEndChild( text ); + item.InsertEndChild( meeting1 ); + item.InsertEndChild( meeting2 ); + + // And add the node to the existing list after the first child. + node = todoElement->FirstChild( "Item" ); + assert( node ); + itemElement = node->ToElement(); + assert( itemElement ); + + todoElement->InsertAfterChild( itemElement, item ); + + printf( "\n** Demo doc processed: ** \n\n" ); + doc.Print( stdout ); + + + #ifdef TIXML_USE_STL + printf( "** Demo doc processed to stream: ** \n\n" ); + cout << doc << endl << endl; + #endif + + // -------------------------------------------------------- + // Different tests...do we have what we expect? + // -------------------------------------------------------- + + int count = 0; + TiXmlElement* element; + + ////////////////////////////////////////////////////// + + #ifdef TIXML_USE_STL + cout << "** Basic structure. **\n"; + ostringstream outputStream( ostringstream::out ); + outputStream << doc; + XmlTest( "Output stream correct.", string( demoEnd ).c_str(), + outputStream.str().c_str(), true ); + #endif + + node = doc.RootElement(); + assert( node ); + XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) ); + XmlTest ( "Root element value is 'ToDo'.", "ToDo", node->Value()); + + node = node->FirstChild(); + XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) ); + node = node->NextSibling(); + XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) ); + XmlTest ( "Value is 'Item'.", "Item", node->Value() ); + + node = node->FirstChild(); + XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) ); + XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() ); + + + ////////////////////////////////////////////////////// + printf ("\n** Iterators. **\n"); + + // Walk all the top level nodes of the document. + count = 0; + for( node = doc.FirstChild(); + node; + node = node->NextSibling() ) + { + count++; + } + XmlTest( "Top level nodes, using First / Next.", 3, count ); + + count = 0; + for( node = doc.LastChild(); + node; + node = node->PreviousSibling() ) + { + count++; + } + XmlTest( "Top level nodes, using Last / Previous.", 3, count ); + + // Walk all the top level nodes of the document, + // using a different syntax. + count = 0; + for( node = doc.IterateChildren( 0 ); + node; + node = doc.IterateChildren( node ) ) + { + count++; + } + XmlTest( "Top level nodes, using IterateChildren.", 3, count ); + + // Walk all the elements in a node. + count = 0; + for( element = todoElement->FirstChildElement(); + element; + element = element->NextSiblingElement() ) + { + count++; + } + XmlTest( "Children of the 'ToDo' element, using First / Next.", + 3, count ); + + // Walk all the elements in a node by value. + count = 0; + for( node = todoElement->FirstChild( "Item" ); + node; + node = node->NextSibling( "Item" ) ) + { + count++; + } + XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count ); + + count = 0; + for( node = todoElement->LastChild( "Item" ); + node; + node = node->PreviousSibling( "Item" ) ) + { + count++; + } + XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count ); + + #ifdef TIXML_USE_STL + { + cout << "\n** Parsing. **\n"; + istringstream parse0( "" ); + TiXmlElement element0( "default" ); + parse0 >> element0; + + XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() ); + XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" )); + XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) ); + XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) ); + } + #endif + + { + const char* error = "\n" + "\n" + " \n" + ""; + + TiXmlDocument docTest; + docTest.Parse( error ); + XmlTest( "Error row", docTest.ErrorRow(), 3 ); + XmlTest( "Error column", docTest.ErrorCol(), 17 ); + //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 ); + + } + + #ifdef TIXML_USE_STL + { + ////////////////////////////////////////////////////// + cout << "\n** Streaming. **\n"; + + // Round trip check: stream in, then stream back out to verify. The stream + // out has already been checked, above. We use the output + + istringstream inputStringStream( outputStream.str() ); + TiXmlDocument document0; + + inputStringStream >> document0; + + ostringstream outputStream0( ostringstream::out ); + outputStream0 << document0; + + XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(), + outputStream0.str().c_str(), true ); + + std::string str; + str << document0; + + XmlTest( "String printing correct.", string( demoEnd ).c_str(), + str.c_str(), true ); + } + #endif + } + + { + const char* str = ""; + + TiXmlDocument doc; + doc.Parse( str ); + + TiXmlElement* ele = doc.FirstChildElement(); + + int iVal, result; + double dVal; + + result = ele->QueryDoubleAttribute( "attr0", &dVal ); + XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS ); + XmlTest( "Query attribute: int as double", (int)dVal, 1 ); + result = ele->QueryDoubleAttribute( "attr1", &dVal ); + XmlTest( "Query attribute: double as double", (int)dVal, 2 ); + result = ele->QueryIntAttribute( "attr1", &iVal ); + XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS ); + XmlTest( "Query attribute: double as int", iVal, 2 ); + result = ele->QueryIntAttribute( "attr2", &iVal ); + XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE ); + result = ele->QueryIntAttribute( "bar", &iVal ); + XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE ); + } + + { + const char* str = "\t\t\n" + ""; + + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Parse( str ); + + TiXmlHandle docHandle( &doc ); + TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" ); + + assert( docHandle.Node() ); + assert( roomHandle.Element() ); + + TiXmlElement* room = roomHandle.Element(); + assert( room ); + TiXmlAttribute* doors = room->FirstAttribute(); + assert( doors ); + + XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 ); + XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 ); + XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 ); + XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 ); + } + + { + const char* str = "\t\t\n" + " \n" + " A great door!\n" + "\t" + ""; + + TiXmlDocument doc; + doc.Parse( str ); + + TiXmlHandle docHandle( &doc ); + TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" ); + TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild(); + TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild(); + TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 ); + TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 ); + + assert( docHandle.Node() ); + assert( roomHandle.Element() ); + assert( commentHandle.Node() ); + assert( textHandle.Text() ); + assert( door0Handle.Element() ); + assert( door1Handle.Element() ); + + TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration(); + assert( declaration ); + TiXmlElement* room = roomHandle.Element(); + assert( room ); + TiXmlAttribute* doors = room->FirstAttribute(); + assert( doors ); + TiXmlText* text = textHandle.Text(); + TiXmlComment* comment = commentHandle.Node()->ToComment(); + assert( comment ); + TiXmlElement* door0 = door0Handle.Element(); + TiXmlElement* door1 = door1Handle.Element(); + + XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 ); + XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 ); + XmlTest( "Location tracking: room row", room->Row(), 1 ); + XmlTest( "Location tracking: room col", room->Column(), 45 ); + XmlTest( "Location tracking: doors row", doors->Row(), 1 ); + XmlTest( "Location tracking: doors col", doors->Column(), 51 ); + XmlTest( "Location tracking: Comment row", comment->Row(), 2 ); + XmlTest( "Location tracking: Comment col", comment->Column(), 3 ); + XmlTest( "Location tracking: text row", text->Row(), 3 ); + XmlTest( "Location tracking: text col", text->Column(), 24 ); + XmlTest( "Location tracking: door0 row", door0->Row(), 3 ); + XmlTest( "Location tracking: door0 col", door0->Column(), 5 ); + XmlTest( "Location tracking: door1 row", door1->Row(), 4 ); + XmlTest( "Location tracking: door1 col", door1->Column(), 5 ); + } + + + // -------------------------------------------------------- + // UTF-8 testing. It is important to test: + // 1. Making sure name, value, and text read correctly + // 2. Row, Col functionality + // 3. Correct output + // -------------------------------------------------------- + printf ("\n** UTF-8 **\n"); + { + TiXmlDocument doc( "utf8test.xml" ); + doc.LoadFile(); + if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) { + printf( "WARNING: File 'utf8test.xml' not found.\n" + "(Are you running the test from the wrong directory?)\n" + "Could not test UTF-8 functionality.\n" ); + } + else + { + TiXmlHandle docH( &doc ); + // Get the attribute "value" from the "Russian" element and check it. + TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element(); + const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, + 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 }; + + XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true ); + XmlTest( "UTF-8: Russian value row.", 4, element->Row() ); + XmlTest( "UTF-8: Russian value column.", 5, element->Column() ); + + const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U, + 0xd1U, 0x81U, 0xd1U, 0x81U, + 0xd0U, 0xbaU, 0xd0U, 0xb8U, + 0xd0U, 0xb9U, 0 }; + const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>"; + + TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text(); + XmlTest( "UTF-8: Browsing russian element name.", + russianText, + text->Value(), + true ); + XmlTest( "UTF-8: Russian element name row.", 7, text->Row() ); + XmlTest( "UTF-8: Russian element name column.", 47, text->Column() ); + + TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration(); + XmlTest( "UTF-8: Declaration column.", 1, dec->Column() ); + XmlTest( "UTF-8: Document column.", 1, doc.Column() ); + + // Now try for a round trip. + doc.SaveFile( "utf8testout.xml" ); + + // Check the round trip. + char savedBuf[256]; + char verifyBuf[256]; + int okay = 1; + + FILE* saved = fopen( "utf8testout.xml", "r" ); + FILE* verify = fopen( "utf8testverify.xml", "r" ); + if ( saved && verify ) + { + while ( fgets( verifyBuf, 256, verify ) ) + { + fgets( savedBuf, 256, saved ); + if ( strcmp( verifyBuf, savedBuf ) ) + { + okay = 0; + break; + } + } + fclose( saved ); + fclose( verify ); + } + XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay ); + + // On most Western machines, this is an element that contains + // the word "resume" with the correct accents, in a latin encoding. + // It will be something else completely on non-wester machines, + // which is why TinyXml is switching to UTF-8. + const char latin[] = "r\x82sum\x82"; + + TiXmlDocument latinDoc; + latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY ); + + text = latinDoc.FirstChildElement()->FirstChild()->ToText(); + XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() ); + } + } + + ////////////////////// + // Copy and assignment + ////////////////////// + printf ("\n** Copy and Assignment **\n"); + { + TiXmlElement element( "foo" ); + element.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); + + TiXmlElement elementCopy( element ); + TiXmlElement elementAssign( "foo" ); + elementAssign.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); + elementAssign = element; + + XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() ); + XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) ); + XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() ); + XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) ); + XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) ); + + TiXmlComment comment; + comment.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); + TiXmlComment commentCopy( comment ); + TiXmlComment commentAssign; + commentAssign = commentCopy; + XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() ); + XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() ); + + TiXmlUnknown unknown; + unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN ); + TiXmlUnknown unknownCopy( unknown ); + TiXmlUnknown unknownAssign; + unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN ); + unknownAssign = unknownCopy; + XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() ); + XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() ); + + TiXmlText text( "TextNode" ); + TiXmlText textCopy( text ); + TiXmlText textAssign( "incorrect" ); + textAssign = text; + XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() ); + XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() ); + + TiXmlDeclaration dec; + dec.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); + TiXmlDeclaration decCopy( dec ); + TiXmlDeclaration decAssign; + decAssign = dec; + + XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() ); + XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() ); + + TiXmlDocument doc; + elementCopy.InsertEndChild( textCopy ); + doc.InsertEndChild( decAssign ); + doc.InsertEndChild( elementCopy ); + doc.InsertEndChild( unknownAssign ); + + TiXmlDocument docCopy( doc ); + TiXmlDocument docAssign; + docAssign = docCopy; + + #ifdef TIXML_USE_STL + std::string original, copy, assign; + original << doc; + copy << docCopy; + assign << docAssign; + XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true ); + XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true ); + + #endif + } + + ////////////////////////////////////////////////////// +#ifdef TIXML_USE_STL + printf ("\n** Parsing, no Condense Whitespace **\n"); + TiXmlBase::SetCondenseWhiteSpace( false ); + { + istringstream parse1( "This is \ntext" ); + TiXmlElement text1( "text" ); + parse1 >> text1; + + XmlTest ( "Condense white space OFF.", "This is \ntext", + text1.FirstChild()->Value(), + true ); + } + TiXmlBase::SetCondenseWhiteSpace( true ); +#endif + + ////////////////////////////////////////////////////// + // GetText(); + { + const char* str = "This is text"; + TiXmlDocument doc; + doc.Parse( str ); + const TiXmlElement* element = doc.RootElement(); + + XmlTest( "GetText() normal use.", "This is text", element->GetText() ); + + str = "This is text"; + doc.Clear(); + doc.Parse( str ); + element = doc.RootElement(); + + XmlTest( "GetText() contained element.", element->GetText() == 0, true ); + + str = "This is text"; + doc.Clear(); + TiXmlBase::SetCondenseWhiteSpace( false ); + doc.Parse( str ); + TiXmlBase::SetCondenseWhiteSpace( true ); + element = doc.RootElement(); + + XmlTest( "GetText() partial.", "This is ", element->GetText() ); + } + + + ////////////////////////////////////////////////////// + // CDATA + { + const char* str = "" + " the rules!\n" + "...since I make symbolic puns" + "]]>" + ""; + TiXmlDocument doc; + doc.Parse( str ); + doc.Print(); + + XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + + #ifdef TIXML_USE_STL + //cout << doc << '\n'; + + doc.Clear(); + + istringstream parse0( str ); + parse0 >> doc; + //cout << doc << '\n'; + + XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + #endif + + TiXmlDocument doc1 = doc; + //doc.Print(); + + XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + } + { + // [ 1482728 ] Wrong wide char parsing + char buf[256]; + buf[255] = 0; + for( int i=0; i<255; ++i ) { + buf[i] = (char)((i>=32) ? i : 32); + } + TIXML_STRING str( ""; + + TiXmlDocument doc; + doc.Parse( str.c_str() ); + + TiXmlPrinter printer; + printer.SetStreamPrinting(); + doc.Accept( &printer ); + + XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true ); + + #ifdef TIXML_USE_STL + doc.Clear(); + istringstream iss( printer.Str() ); + iss >> doc; + std::string out; + out << doc; + XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true ); + #endif + } + { + // [ 1480107 ] Bug-fix for STL-streaming of CDATA that contains tags + // CDATA streaming had a couple of bugs, that this tests for. + const char* str = "" + "I am > the rules!\n" + "...since I make symbolic puns" + "]]>" + ""; + TiXmlDocument doc; + doc.Parse( str ); + doc.Print(); + + XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + + #ifdef TIXML_USE_STL + + doc.Clear(); + + istringstream parse0( str ); + parse0 >> doc; + + XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + #endif + + TiXmlDocument doc1 = doc; + //doc.Print(); + + XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(), + "I am > the rules!\n...since I make symbolic puns", + true ); + } + ////////////////////////////////////////////////////// + // Visit() + + + + ////////////////////////////////////////////////////// + printf( "\n** Fuzzing... **\n" ); + + const int FUZZ_ITERATION = 300; + + // The only goal is not to crash on bad input. + int len = (int) strlen( demoStart ); + for( int i=0; i" + "" + " " + ""; + + TiXmlDocument doc( "passages.xml" ); + doc.Parse( passages ); + TiXmlElement* psg = doc.RootElement()->FirstChildElement(); + const char* context = psg->Attribute( "context" ); + const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9."; + + XmlTest( "Entity transformation: read. ", expected, context, true ); + + FILE* textfile = fopen( "textfile.txt", "w" ); + if ( textfile ) + { + psg->Print( textfile, 0 ); + fclose( textfile ); + } + textfile = fopen( "textfile.txt", "r" ); + assert( textfile ); + if ( textfile ) + { + char buf[ 1024 ]; + fgets( buf, 1024, textfile ); + XmlTest( "Entity transformation: write. ", + "", + buf, + true ); + } + fclose( textfile ); + } + + { + FILE* textfile = fopen( "test5.xml", "w" ); + if ( textfile ) + { + fputs("", textfile); + fclose(textfile); + + TiXmlDocument doc; + doc.LoadFile( "test5.xml" ); + XmlTest( "dot in element attributes and names", doc.Error(), 0); + } + } + + { + FILE* textfile = fopen( "test6.xml", "w" ); + if ( textfile ) + { + fputs("1.1 Start easy ignore fin thickness ", textfile ); + fclose(textfile); + + TiXmlDocument doc; + bool result = doc.LoadFile( "test6.xml" ); + XmlTest( "Entity with one digit.", result, true ); + + TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText(); + XmlTest( "Entity with one digit.", + text->Value(), "1.1 Start easy ignore fin thickness\n" ); + } + } + + { + // DOCTYPE not preserved (950171) + // + const char* doctype = + "" + "" + "" + "" + ""; + + TiXmlDocument doc; + doc.Parse( doctype ); + doc.SaveFile( "test7.xml" ); + doc.Clear(); + doc.LoadFile( "test7.xml" ); + + TiXmlHandle docH( &doc ); + TiXmlUnknown* unknown = docH.Child( 1 ).Unknown(); + XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() ); + #ifdef TIXML_USE_STL + TiXmlNode* node = docH.Child( 2 ).Node(); + std::string str; + str << (*node); + XmlTest( "Correct streaming of unknown.", "", str.c_str() ); + #endif + } + + { + // [ 791411 ] Formatting bug + // Comments do not stream out correctly. + const char* doctype = + ""; + TiXmlDocument doc; + doc.Parse( doctype ); + + TiXmlHandle docH( &doc ); + TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment(); + + XmlTest( "Comment formatting.", " Somewhat ", comment->Value() ); + #ifdef TIXML_USE_STL + std::string str; + str << (*comment); + XmlTest( "Comment streaming.", "", str.c_str() ); + #endif + } + + { + // [ 870502 ] White space issues + TiXmlDocument doc; + TiXmlText* text; + TiXmlHandle docH( &doc ); + + const char* doctype0 = " This has leading and trailing space "; + const char* doctype1 = "This has internal space"; + const char* doctype2 = " This has leading, trailing, and internal space "; + + TiXmlBase::SetCondenseWhiteSpace( false ); + doc.Clear(); + doc.Parse( doctype0 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() ); + + doc.Clear(); + doc.Parse( doctype1 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space kept.", "This has internal space", text->Value() ); + + doc.Clear(); + doc.Parse( doctype2 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space kept.", " This has leading, trailing, and internal space ", text->Value() ); + + TiXmlBase::SetCondenseWhiteSpace( true ); + doc.Clear(); + doc.Parse( doctype0 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() ); + + doc.Clear(); + doc.Parse( doctype1 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space condensed.", "This has internal space", text->Value() ); + + doc.Clear(); + doc.Parse( doctype2 ); + text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); + XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() ); + } + + { + // Double attributes + const char* doctype = ""; + + TiXmlDocument doc; + doc.Parse( doctype ); + + XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an error to tinyxml + XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) ); + } + + { + // Embedded null in stream. + const char* doctype = ""; + + TiXmlDocument doc; + doc.Parse( doctype ); + XmlTest( "Embedded null throws error.", true, doc.Error() ); + + #ifdef TIXML_USE_STL + istringstream strm( doctype ); + doc.Clear(); + doc.ClearError(); + strm >> doc; + XmlTest( "Embedded null throws error.", true, doc.Error() ); + #endif + } + + { + // Legacy mode test. (This test may only pass on a western system) + const char* str = + "" + "<�>" + "C�nt�nt�������" + ""; + + TiXmlDocument doc; + doc.Parse( str ); + + TiXmlHandle docHandle( &doc ); + TiXmlHandle aHandle = docHandle.FirstChildElement( "�" ); + TiXmlHandle tHandle = aHandle.Child( 0 ); + assert( aHandle.Element() ); + assert( tHandle.Text() ); + XmlTest( "ISO-8859-1 Parsing.", "C�nt�nt�������", tHandle.Text()->Value() ); + } + + { + // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717 + const char* str = " "; + TiXmlDocument doc; + doc.Parse( str ); + XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() ); + } + #ifndef TIXML_USE_STL + { + // String equality. [ 1006409 ] string operator==/!= no worky in all cases + TiXmlString temp; + XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true ); + + TiXmlString foo; + TiXmlString bar( "" ); + XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true ); + } + + #endif + { + // Bug [ 1195696 ] from marlonism + TiXmlBase::SetCondenseWhiteSpace(false); + TiXmlDocument xml; + xml.Parse("This hangs"); + XmlTest( "Test safe error return.", xml.Error(), false ); + } + + { + // Bug [ 1243992 ] - another infinite loop + TiXmlDocument doc; + doc.SetCondenseWhiteSpace(false); + doc.Parse("

test

"); + } + { + // Low entities + TiXmlDocument xml; + xml.Parse( "" ); + const char result[] = { 0x0e, 0 }; + XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result ); + xml.Print(); + } + { + // Bug [ 1451649 ] Attribute values with trailing quotes not handled correctly + TiXmlDocument xml; + xml.Parse( "" ); + XmlTest( "Throw error with bad end quotes.", xml.Error(), true ); + } + #ifdef TIXML_USE_STL + { + // Bug [ 1449463 ] Consider generic query + TiXmlDocument xml; + xml.Parse( "" ); + + TiXmlElement* ele = xml.FirstChildElement(); + double d; + int i; + float f; + bool b; + //std::string str; + + XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS ); + XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS ); + XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS ); + XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE ); + XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE ); + //XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS ); + + XmlTest( "QueryValueAttribute", (d==3.0), true ); + XmlTest( "QueryValueAttribute", (i==3), true ); + XmlTest( "QueryValueAttribute", (f==3.0f), true ); + //XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true ); + } + #endif + + #ifdef TIXML_USE_STL + { + // [ 1505267 ] redundant malloc in TiXmlElement::Attribute + TiXmlDocument xml; + xml.Parse( "" ); + TiXmlElement* ele = xml.FirstChildElement(); + double d; + int i; + + std::string bar = "bar"; + + const std::string* atrrib = ele->Attribute( bar ); + ele->Attribute( bar, &d ); + ele->Attribute( bar, &i ); + + XmlTest( "Attribute", atrrib->empty(), false ); + XmlTest( "Attribute", (d==3.0), true ); + XmlTest( "Attribute", (i==3), true ); + } + #endif + + { + // [ 1356059 ] Allow TiXMLDocument to only be at the top level + TiXmlDocument xml, xml2; + xml.InsertEndChild( xml2 ); + XmlTest( "Document only at top level.", xml.Error(), true ); + XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY ); + } + + { + // [ 1663758 ] Failure to report error on bad XML + TiXmlDocument xml; + xml.Parse(""); + XmlTest("Missing end tag at end of input", xml.Error(), true); + xml.Parse(" "); + XmlTest("Missing end tag with trailing whitespace", xml.Error(), true); + } + + { + // [ 1635701 ] fail to parse files with a tag separated into two lines + // I'm not sure this is a bug. Marked 'pending' for feedback. + TiXmlDocument xml; + xml.Parse( "<p>text</p\n><title>" ); + //xml.Print(); + //XmlTest( "Tag split by newline", xml.Error(), false ); + } + + #ifdef TIXML_USE_STL + { + // [ 1475201 ] TinyXML parses entities in comments + TiXmlDocument xml; + istringstream parse1( "<!-- declarations for <head> & <body> -->" + "<!-- far & away -->" ); + parse1 >> xml; + + TiXmlNode* e0 = xml.FirstChild(); + TiXmlNode* e1 = e0->NextSibling(); + TiXmlComment* c0 = e0->ToComment(); + TiXmlComment* c1 = e1->ToComment(); + + XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); + XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); + } + #endif + + { + // [ 1475201 ] TinyXML parses entities in comments + TiXmlDocument xml; + xml.Parse("<!-- declarations for <head> & <body> -->" + "<!-- far & away -->" ); + + TiXmlNode* e0 = xml.FirstChild(); + TiXmlNode* e1 = e0->NextSibling(); + TiXmlComment* c0 = e0->ToComment(); + TiXmlComment* c1 = e1->ToComment(); + + XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); + XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); + } + /* + { + TiXmlDocument xml; + xml.Parse( "<tag>/</tag>" ); + xml.Print(); + xml.FirstChild()->Print( stdout, 0 ); + xml.FirstChild()->Type(); + } + */ + + /* 1417717 experiment + { + TiXmlDocument xml; + xml.Parse("<text>Dan & Tracie</text>"); + xml.Print(stdout); + } + { + TiXmlDocument xml; + xml.Parse("<text>Dan &foo; Tracie</text>"); + xml.Print(stdout); + } + */ + #if defined( WIN32 ) && defined( TUNE ) + _CrtMemCheckpoint( &endMemState ); + //_CrtMemDumpStatistics( &endMemState ); + + _CrtMemState diffMemState; + _CrtMemDifference( &diffMemState, &startMemState, &endMemState ); + _CrtMemDumpStatistics( &diffMemState ); + #endif + + printf ("\nPass %d, Fail %d\n", gPass, gFail); + return gFail; +} + + diff --git a/src/Plugins/AgtDummy/Dummy.cpp b/src/Plugins/AgtDummy/Dummy.cpp new file mode 100644 index 00000000..cf262873 --- /dev/null +++ b/src/Plugins/AgtDummy/Dummy.cpp @@ -0,0 +1,75 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Dummy.cpp + * @brief Plugin for dummy pedestrian. + */ + +#include "DummyConfig.h" +#include "DummyDBEntry.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" DUMMY_API const char * getName() { + return "Dummy Pedestrian Model"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" DUMMY_API const char * getDescription() { + return "A simple example of a pedestrian model. The dummy model computes a " \ + "new velocity by randomly perturbing the preferred velocity."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" DUMMY_API void registerPlugin( PluginEngine * engine ) { + engine->registerModelDBEntry( new Dummy::DummyDBEntry() ); +} + diff --git a/src/Plugins/AgtDummy/Dummy.h b/src/Plugins/AgtDummy/Dummy.h new file mode 100644 index 00000000..a35072d8 --- /dev/null +++ b/src/Plugins/AgtDummy/Dummy.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Dummy.h + * @brief Collection of Dummy Agent and Simulator for simple inclusion. + */ + +#ifndef __DUMMY_H__ +#define __DUMMY_H__ + +#include "DummySimulator.h" +#include "DummyAgent.h" + +#endif // __DUMMY_H__ diff --git a/src/Plugins/AgtDummy/DummyAgent.cpp b/src/Plugins/AgtDummy/DummyAgent.cpp new file mode 100644 index 00000000..0fdf0803 --- /dev/null +++ b/src/Plugins/AgtDummy/DummyAgent.cpp @@ -0,0 +1,72 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "DummyAgent.h" +#include "DummySimulator.h" + +namespace Dummy { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of Dummy::Agent + ///////////////////////////////////////////////////////////////////////////// + + Agent::Agent() { + } + + ///////////////////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + ///////////////////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + float speedDelta, angle; + + // Generating random numbers is not thread-safe because the generators + // belong to the simulator. + #pragma omp critical + { + // compute random deviation + speedDelta = Simulator::_speedDeviation.getValue() / Simulator::TIME_STEP; + angle = Simulator::_angleDeviation.getValue(); + } + Vector2 deviation( cos( angle ) * speedDelta, sin( angle ) * speedDelta ); + _velNew.set( _velPref.getPreferredVel() + deviation ); + } +} // namespace Dummy \ No newline at end of file diff --git a/src/Plugins/AgtDummy/DummyAgent.h b/src/Plugins/AgtDummy/DummyAgent.h new file mode 100644 index 00000000..e9d9766a --- /dev/null +++ b/src/Plugins/AgtDummy/DummyAgent.h @@ -0,0 +1,79 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file DummyAgent.h + * @brief The definition of a simple "dummy" agent. + */ + +#ifndef __DUMMY_AGENT_H__ +#define __DUMMY_AGENT_H__ + +#include "BaseAgent.h" + +using namespace Menge; + + +namespace Dummy { + /*! + * @brief The "dummy" agent class. + * + * The dummy agent does nothing clever or even correct. Given + * the preferred velocity, its final velocity is simply a random + * perturbation of the preferred velocity. + */ + class Agent : public Agents::BaseAgent { + public: + /*! + * @brief Constructor + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + }; +} // namespace Dummy + +#endif // __DUMMY_AGENT_H__ diff --git a/src/Plugins/AgtDummy/DummyConfig.h b/src/Plugins/AgtDummy/DummyConfig.h new file mode 100644 index 00000000..99771ed5 --- /dev/null +++ b/src/Plugins/AgtDummy/DummyConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file DummyConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __DUMMY_CONFIG_H__ +#define __DUMMY_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( DUMMY_STATICLIB ) + #define DUMMY_API + #else + #if defined( DUMMY_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define DUMMY_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define DUMMY_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( DUMMY_STATICLIB ) + #define DUMMY_API + #else + #if defined( DUMMY_EXPORT ) + #define DUMMY_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define DUMMY_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __DUMMY_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/AgtDummy/DummyDBEntry.cpp b/src/Plugins/AgtDummy/DummyDBEntry.cpp new file mode 100644 index 00000000..5df4aa4f --- /dev/null +++ b/src/Plugins/AgtDummy/DummyDBEntry.cpp @@ -0,0 +1,82 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "DummyDBEntry.h" +#include "DummySimulator.h" +#include "AgentInitializer.h" +#include "SimulatorDB.h" +#include <iostream> + +namespace Dummy { + ///////////////////////////////////////////////////////////////////////////// + // Implementation of DummyDBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DummyDBEntry::briefDescription() const { + return "Dummy simulator to illustrate introduction of pedestrian models."; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DummyDBEntry::longDescription() const { + return "Dummy simulator to illustrate introduction of pedestrian models.\n" + "\tThe agents in this dummy model compute a new velocity by randomly\n" + "\tperturbing the preferred velocity."; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DummyDBEntry::viewerName() const { + return "Dummy Pedestrian"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * DummyDBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * DummyDBEntry::getAgentInitalizer() const { + return new Agents::AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// + +} // namespace Dummy + diff --git a/src/Plugins/AgtDummy/DummyDBEntry.h b/src/Plugins/AgtDummy/DummyDBEntry.h new file mode 100644 index 00000000..fd6c13ee --- /dev/null +++ b/src/Plugins/AgtDummy/DummyDBEntry.h @@ -0,0 +1,113 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file DummyDBEntry.h + * @brief The simulator database entry for the Dummy pedestrian model. + */ + +#ifndef __DUMMY_DB_ENTRY_H__ +#define __DUMMY_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "Dummy.h" + +using namespace Menge; + + +namespace Dummy { + /*! + * @brief The simulator database entry for the Dummy simulator. + */ + class DummyDBEntry : public SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "dummy"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + }; +} // namespace Dummy +#endif // __DUMMY_DB_ENTRY_H__ \ No newline at end of file diff --git a/src/Plugins/AgtDummy/DummySimulator.cpp b/src/Plugins/AgtDummy/DummySimulator.cpp new file mode 100644 index 00000000..623adb26 --- /dev/null +++ b/src/Plugins/AgtDummy/DummySimulator.cpp @@ -0,0 +1,68 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "DummySimulator.h" +#include "Utils.h" +#include "consts.h" + +namespace Dummy { + //////////////////////////////////////////////////////////////// + // Implementation of Dummy::Simulator + //////////////////////////////////////////////////////////////// + + NormalFloatGenerator Simulator::_speedDeviation( 0.f, 0.f, 0.f, 0.f ); + UniformFloatGenerator Simulator::_angleDeviation( 0.f, TWOPI ); + + //////////////////////////////////////////////////////////////// + + bool Simulator::setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ) { + try { + if ( paramName == "stddev" ) { + float stddev = toFloat( value ); + const float HALF_RANGE = 3.f * stddev; + _speedDeviation.set( 0.f, stddev, -HALF_RANGE, HALF_RANGE ); + } else if ( ! Agents::SimulatorBase<Agent>::setExpParam( paramName, value ) ) { + // Simulator base didn't recognize the parameter either + return false; + } + } catch ( UtilException ) { + throw Agents::XMLParamException( std::string( "Dummy parameter \"") + paramName + std::string("\" value couldn't be converted to the correct type. Found the value: " ) + value ); + } + return true; + } +} //namespace Dummy diff --git a/src/Plugins/AgtDummy/DummySimulator.h b/src/Plugins/AgtDummy/DummySimulator.h new file mode 100644 index 00000000..f243a7f2 --- /dev/null +++ b/src/Plugins/AgtDummy/DummySimulator.h @@ -0,0 +1,116 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file DummySimulator.h + * @brief Contains the Dummy::Simulator class. + */ + +#ifndef __DUMMY_SIMULATOR_H__ +#define __DUMMY_SIMULATOR_H__ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "DummyAgent.h" +#include "RandGenerator.h" + +using namespace Menge; + + +/*! + * @namespace Dummy + * @brief The name space for the Dummy pedestrian model. + * + * The dummy pedestrian model is an incredibly simple example model. + * Agents compute a new velocity by randomly perturbing their preferred + * velocity. It is an example of the minimum implementation necessary + * to create a pedestrian model plug-in. + */ +namespace Dummy { + /*! + * @brief The simulator for the Dummy pedestrian model. + */ + class Simulator : public Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator(): Agents::SimulatorBase< Agent >() {} + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * @param tagName the name of the considered tag + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return tagName == "Dummy"; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns whether or not parameters were successfully set + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ); + + protected: + friend class Agent; + + /*! + * @brief The standard deviation of speed + */ + static NormalFloatGenerator _speedDeviation; + + /*! + * @brief The uniform distribution of direction + */ + static UniformFloatGenerator _angleDeviation; + }; +} // namespace Dummy + +#endif // __DUMMY_SIMULATOR_H__ diff --git a/src/Plugins/AgtHelbing/Helbing.cpp b/src/Plugins/AgtHelbing/Helbing.cpp new file mode 100644 index 00000000..e83a3121 --- /dev/null +++ b/src/Plugins/AgtHelbing/Helbing.cpp @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Helbing.cpp + * @brief Plugin for helbing pedestrian. + */ + +#include "HelbingConfig.h" +#include "HelbingDBEntry.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" HELBING_API const char * getName() { + return "Helbing 2000 Pedestrian Model"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" HELBING_API const char * getDescription() { + return "A pedestran plugin based on the model proposed in 2000 by Helbing et al."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" HELBING_API void registerPlugin( PluginEngine * engine ) { + engine->registerModelDBEntry( new Helbing::DBEntry() ); +} + diff --git a/src/Plugins/AgtHelbing/Helbing.h b/src/Plugins/AgtHelbing/Helbing.h new file mode 100644 index 00000000..feb34936 --- /dev/null +++ b/src/Plugins/AgtHelbing/Helbing.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Helbing.h + * @brief The definition of the Helbing pedestrian plug-in + */ + +#ifndef __HELBING_H__ +#define __HELBING_H__ + +#include "HelbingAgent.h" +#include "HelbingSimulator.h" + +#endif //__HELBING_H__ \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingAgent.cpp b/src/Plugins/AgtHelbing/HelbingAgent.cpp new file mode 100644 index 00000000..212bd560 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingAgent.cpp @@ -0,0 +1,194 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HelbingAgent.h" +#include "HelbingSimulator.h" +#include "Math/geomQuery.h" + +namespace Helbing { + //////////////////////////////////////////////////////////////// + // Implementation of Helbing::Agent + //////////////////////////////////////////////////////////////// + + // mass = 80 Kg comes from Helbing's 2000 paper + Agent::Agent(): Agents::BaseAgent() { + _mass = 80.f; + } + + //////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + //////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + Vector2 force( drivingForce() ); + for ( size_t i = 0; i < _nearAgents.size(); ++i ) { + const Agents::BaseAgent * otherBase = _nearAgents[i].agent; + const Agent * const other = static_cast< const Agent *>( otherBase ); + + force += agentForce( other ); + } + + for ( size_t obs = 0; obs < _nearObstacles.size(); ++obs ) { + const Agents::Obstacle * obst = _nearObstacles[ obs ].obstacle; + force += obstacleForce( obst ); + } + Vector2 acc = force / _mass; + _velNew = _vel + acc * Simulator::TIME_STEP; + } + + //////////////////////////////////////////////////////////////// + + Vector2 Agent::agentForce( const Agent * other ) const { + /* compute right of way */ + float rightOfWay = fabs( _priority - other->_priority ); + if ( rightOfWay >= 1.f ) { + rightOfWay = 1.f; + } + + const float D = Simulator::FORCE_DISTANCE; + Vector2 normal_ij = _pos - other->_pos; + float distance_ij = abs( normal_ij ); + normal_ij /= distance_ij; + float Radii_ij = _radius + other->_radius; + + float AGENT_SCALE = Simulator::AGENT_SCALE; + float D_AGT = D; + + // Right of way-dependent calculations + // Compute the direction perpinduclar to preferred velocity (on the side + // of the normal force. + + Vector2 avoidNorm( normal_ij ); + if ( rightOfWay ) { + Vector2 perpDir; + if ( _priority < other->_priority ) { + // his advantage + D_AGT += ( rightOfWay * rightOfWay ) * _radius * .5f; // Note: there is no symmetric reduction on + // the other side + // modify normal direction + // The perpendicular direction should always be in the direction that gets the + // agent out of the way as easily as possible + float prefSpeed = other->_velPref.getSpeed(); + if ( prefSpeed < 0.0001f ) { + // he wants to be stationary, accelerate perpinduclarly to displacement + perpDir.set( -normal_ij.y(), normal_ij.x() ); + if ( perpDir * _vel < 0.f ) perpDir.negate(); + } else { + // He's moving somewhere, accelerate perpindicularly to his preferred direction + // of travel. + const Vector2 prefDir( other->_velPref.getPreferred() ); + perpDir.set( -prefDir.y(), prefDir.x() ); // perpendicular to preferred velocity + if ( perpDir * normal_ij < 0.f ) perpDir.negate(); + } + // spherical linear interpolation + float sinTheta = det( perpDir, normal_ij ); + if ( sinTheta < 0.f ) { + sinTheta = -sinTheta; + } + if ( sinTheta > 1.f ) { + sinTheta = 1.f; // clean up numerical error arising from determinant + } + avoidNorm.set( slerp( rightOfWay, normal_ij, perpDir, sinTheta ) ); + } + } + float mag = (AGENT_SCALE * expf((Radii_ij - distance_ij)/ D_AGT )); + const float MAX_FORCE = 1e15f; + if ( mag >= MAX_FORCE ) { + mag = MAX_FORCE; + } + Vector2 force( avoidNorm * mag ); + + if (distance_ij < Radii_ij) { + Vector2 f_pushing( 0.f, 0.f ); + Vector2 f_friction( 0.f, 0.f ); + // pushing + Vector2 tangent_ij( normal_ij.y(), -normal_ij.x() ); + + f_pushing = normal_ij * ( Simulator::BODY_FORCE * (Radii_ij - distance_ij)); + f_friction = tangent_ij * (Simulator::FRICTION * (Radii_ij - distance_ij)) * fabs(( other->_vel - _vel ) * tangent_ij);// / distance_ij; + force += f_pushing + f_friction; + } + return force; + } + + //////////////////////////////////////////////////////////////// + + Vector2 Agent::obstacleForce( const Agents::Obstacle * obst ) const { + const float D = Simulator::FORCE_DISTANCE; + const float OBST_MAG = Simulator::OBST_SCALE; + Vector2 nearPt; // set by distanceSqToPoint + float distSq; // set by distanceSqToPoint + if ( obst->distanceSqToPoint( _pos, nearPt, distSq ) == Agents::Obstacle::LAST ) return Vector2(0.f,0.f); + float dist = sqrtf( distSq ); + Vector2 forceDir( ( _pos - nearPt ) / dist ); + + Vector2 force = forceDir * (OBST_MAG * exp( ( _radius - dist ) / D)); + + // pushing, friction + if (dist < _radius) { // intersection has occurred + Vector2 f_pushing(0.f, 0.f); + Vector2 f_friction(0.f, 0.f); + + Vector2 tangent_io( forceDir.y(), -forceDir.x()); + + // make sure direction is opposite i's velocity + if ( ( tangent_io * _vel) < 0.f) { + tangent_io.negate(); + } + + f_pushing = forceDir * (Simulator::BODY_FORCE * ( _radius - dist ) ); + + // friction + f_friction = tangent_io * Simulator::FRICTION * ( _radius - dist ) * ( _vel * tangent_io); + force += f_pushing - f_friction; + } + return force; + } + + //////////////////////////////////////////////////////////////// + + Vector2 Agent::drivingForce() const { + return ( _velPref.getPreferredVel() - _vel ) * ( _mass / Simulator::REACTION_TIME ); + } + + //////////////////////////////////////////////////////////////// + +} // namespace Helbing \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingAgent.h b/src/Plugins/AgtHelbing/HelbingAgent.h new file mode 100644 index 00000000..5974d346 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingAgent.h @@ -0,0 +1,101 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HelbingAgent.h + * @brief The agent specification for the pedestrian model based + * on the Helbing et al., 2000 paper. + */ + +#ifndef __HELBING_AGENT_H__ +#define __HELBING_AGENT_H__ + +#include "BaseAgent.h" + +using namespace Menge; + + +namespace Helbing { + /*! + * @brief Agent definition for the Helbing pedestrian model. + */ + class Agent : public Agents::BaseAgent { + public: + /*! + * @brief A variant of the copy constructor. + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief Compute the force due to another agent + * @param other A pointer to a neighboring agent + * @returns The force imparted by the other agent on this agent + */ + Vector2 agentForce( const Agent * other ) const; + + /*! + * @brief Compute the force due to a nearby obstacle + * @param obst A pointer to the obstacle + * @returns The force imparted by the obstacle on this agent + */ + Vector2 obstacleForce( const Agents::Obstacle * obst ) const; + + /*! + * @brief Computes the driving force for the agent + * @returns The vector corresponding to the agent's driving force. + */ + Vector2 drivingForce() const; + + /*! + * @brief The mass of the agent + */ + float _mass; + }; +} // namespace Helbing + +#endif \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingAgentContext.cpp b/src/Plugins/AgtHelbing/HelbingAgentContext.cpp new file mode 100644 index 00000000..d1033434 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingAgentContext.cpp @@ -0,0 +1,288 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HelbingAgentContext.h" +#include "HelbingAgent.h" +#include "VisAgent.h" +#include <iomanip> +#include <sstream> + +namespace Helbing { + + //////////////////////////////////////////////////////////////// + // Implementation of HelbingAgentContext + //////////////////////////////////////////////////////////////// + + AgentContext::AgentContext( VisAgent ** agents, unsigned int agtCount ): BaseAgentContext(agents,agtCount), _showForce(false),_forceObject(0) + { + } + + //////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult AgentContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result = BaseAgentContext::handleKeyboard( e ); + if ( !result.isHandled() ) { + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + + if ( e.type == SDL_KEYDOWN ) { + if ( noMods ) { + if ( e.key.keysym.sym == SDLK_f ) { + _showForce = !_showForce; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_UP ) { + if ( _showForce && _selected ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + int NBRS = (int)agt->_nearAgents.size(); + int OBST = (int)agt->_nearObstacles.size(); + if ( NBRS | OBST ) { + ++_forceObject; + if ( _forceObject > NBRS ) { + if ( OBST ) { + _forceObject = -OBST; + } else { + _forceObject = 0; + } + } + result.set( true, true ); + } + } + } else if ( e.key.keysym.sym == SDLK_DOWN ) { + if ( _showForce && _selected ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + int NBRS = (int)agt->_nearAgents.size(); + int OBST = (int)agt->_nearObstacles.size(); + if ( NBRS | OBST ) { + --_forceObject; + if ( _forceObject < -OBST ) { + if ( NBRS ) { + _forceObject = NBRS; + } else { + _forceObject = -1; + } + } + result.set( true, true ); + } + } + } + } + } + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::update() { + BaseAgentContext::update(); + if ( _selected && _forceObject ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + if ( _forceObject > 0 ) { + int NBR_COUNT = (int)agt->_nearAgents.size(); + if ( _forceObject > NBR_COUNT ) { + _forceObject = NBR_COUNT; + } + } else { // _forceObject < 0 + int OBST_COUNT = (int)agt->_nearObstacles.size(); + if ( -_forceObject > OBST_COUNT ) { + _forceObject = -OBST_COUNT; + } + } + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::draw3DGL( bool select ) { + BaseAgentContext::draw3DGL( select ); + if ( !select && _selected ) { + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + glDepthMask( GL_FALSE ); + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + drawForce( agt ); + glPopAttrib(); + } + } + + //////////////////////////////////////////////////////////////// + + std::string AgentContext::agentText( const Agents::BaseAgent * agent ) const { + const Agent * agt = dynamic_cast< const Agent * >( agent ); + std::string m = BaseAgentContext::agentText( agt ); + + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + ss << "\nMass"; + if ( _selected ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + ss << " " << agt->_mass << " kg"; + } + ss << "\n_________________________"; + ss << "\nDraw (F)orces"; + if ( _showForce && _selected ) { + ss << "\n (up/down arrow to change)"; + if ( _forceObject == 0 ) { + ss << "\n All forces"; + } else if ( _forceObject > 0 ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( _forceObject - 1 ) ); + float force = abs( agt->agentForce( other ) ); + ss << "\n Agent " << other->_id << ": " << force << " N"; + } else if ( _forceObject < 0 ) { + const Agent * agt = dynamic_cast< const Agent * >( _selected->getAgent() ); + assert( agt != 0x0 && "Helbing context trying to work with a non helbing agent" ); + const Agents::Obstacle * obst = agt->getObstacle( -_forceObject - 1 ); + float force = abs( agt->obstacleForce( obst ) ); + ss << "\n Obstacle " << obst->_id << ": " << force << " N"; + } + } + return m + ss.str(); + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::drawForce( const Agent * agt ) { + if ( _showForce && _selected ) { + if ( agt->_nearAgents.size() > 0 ) { + glPushMatrix(); + // Draw driving force + glColor4f( 0.1f, 1.f, 0.1f, 1.f ); + Vector2 driveForce( agt->drivingForce() ); + drawForce( agt, driveForce, "D" ); + // Draw repulsive forces + if ( _forceObject == 0 ) { + // draw forces for all agents + const int NBRS = (int)agt->_nearAgents.size(); + for ( int i = 0; i < NBRS; ++i ) { + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( i ) ); + singleAgentForce( agt, other ); + } + // draw forces for all obstacles + const int OBSTS = (int)agt->_nearObstacles.size(); + for ( int i = 0; i < OBSTS; ++i ) { + const Agents::Obstacle * obst = agt->getObstacle( i ); + singleObstacleForce( agt, obst ); + } + } else if ( _forceObject > 0 ) { + // single agent + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( _forceObject - 1 ) ); + singleAgentForce( agt, other, 0.f ); + } else { + // draw obstacle + const Agents::Obstacle * obst = agt->getObstacle( -_forceObject - 1 ); + singleObstacleForce( agt, obst, 0.f ); + } + glPopMatrix(); + } + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::singleAgentForce( const Agent * agt, const Agent * other, float thresh ) { + Vector2 force = agt->agentForce( other ); + float forceMag = abs( force ); + if ( forceMag > thresh ) { + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + ss << other->_id; + glColor4f( 0.65f, 0.65f, 1.f, 1.f ); + drawForce( agt, force, ss.str() ); + // Label the source agent + writeAlignedText( ss.str(), other->_pos, SceneGraph::TextWriter::CENTERED, true ); + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::singleObstacleForce( const Agent * agt, const Agents::Obstacle * obst, float thresh ) { + Vector2 force = agt->obstacleForce( obst ); + float forceMag = abs( force ); + if ( forceMag > thresh ) { + // Draw the force line + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + ss << obst->_id; + glColor4f( 1.f, 0.65f, 0.65f, 1.f ); + drawForce( agt, force, ss.str() ); + + // Highlight the obstacle + glPushAttrib( GL_LINE_BIT ); + glLineWidth( 3.f ); + glBegin( GL_LINES ); + glVertex3f( obst->getP0().x(), Y, obst->getP0().y() ); + glVertex3f( obst->getP1().x(), Y, obst->getP1().y() ); + glEnd(); + glPopAttrib(); + + // Label the source agent + Vector2 midPoint = obst->midPt(); + writeText( ss.str(), midPoint, true ); + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::drawForce( const Agent * agt, const Vector2 & force, const std::string & label ) { + // This is for printing force magnitude and source + const float FORCE_RADIUS = 4 * agt->_radius; + Vector2 forceEnd = norm( force ) * FORCE_RADIUS + agt->_pos; + glBegin( GL_LINES ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glVertex3f( forceEnd.x(), Y, forceEnd.y() ); + glEnd(); + // annotate illustration + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + // Label the source + if ( label.size() > 0 ) { + ss << label << ": "; + } + ss << abs( force ) << " N"; + writeTextRadially( ss.str(), forceEnd, force, true ); + } +} // namespace Helbing diff --git a/src/Plugins/AgtHelbing/HelbingAgentContext.h b/src/Plugins/AgtHelbing/HelbingAgentContext.h new file mode 100644 index 00000000..2fb561c7 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingAgentContext.h @@ -0,0 +1,161 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HelbingAgentContext.h + * @brief A basic context for interacting with and displaying + * Helbing agent parameters + */ + +#ifndef __HELBING_AGENT_CONTEXT_H__ +#define __HELBING_AGENT_CONTEXT_H__ + +#include "BaseAgentContext.h" +#include "Obstacle.h" + +using namespace Menge; + +namespace Helbing { + // forward declaration + class Agent; + /*! + * @brief The context for displaying the computational aspects of the + * Zanlungo model (see Agents::Helbing::Agent). + */ + class AgentContext : public BaseAgentContext { + public: + /*! + * @brief Constructor. + * + * @param agents An array of pointers to VisAgent instances for Helbing + * agents. + * @param agtCount The number of agents contained in the array. + */ + AgentContext( VisAgent ** agents, unsigned int agtCount ); + + /*! + * @brief Returns the name of the context for display. + * + * @returns The name of this context. + */ + virtual std::string contextName() const { return "Helbing 2000"; } + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + /*! + * @brief Allow the context to update any time-dependent state it might have to + * the given global time. + */ + virtual void update(); + + protected: + /*! + * @brief Draw context elements into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( bool select=false ); + + /*! + * @brief Creates a formatted string to be printed in the context + * for a particular agent + * + * @param agent The agent whose data is to be displayed. + * @returns A formatted string for display in the context's 2D gui. + */ + virtual std::string agentText( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Determines if the force vectors are drawn + */ + bool _showForce; + + /*! + * @brief The id of the forceObject to display. + * If zero, all agents, if positive, a single agent + * if negative, an obstacle + */ + int _forceObject; + + /*! + * @brief Function for drawing the force vectors acting on agt + * + * @param agt The agent whose forces are displayed. + */ + void drawForce( const Agent * agt ); + + /*! + * @brief Draw the force vector from srcAgent acting on agt + * + * @param agt The agent on which the force is acting + * @param other The agent imparting the force + * @param thresh The minimum force magnitude required to draw + */ + void singleAgentForce( const Agent * agt, const Agent * other, float thresh=0.5f ); + + /*! + * @brief Draw the force vector from an obstacle acting on agt + * + * @param agt The agent on which the force is acting + * @param obst The obstacle imparting the force + * @param thresh The minimum force magnitude required to draw + */ + void singleObstacleForce( const Agent * agt, const Agents::Obstacle * obst, float thresh=0.5f ); + + /*! + * @brief Draws the given force on the given agent + * It assumes the force color has already been set. + * + * @param agt A pointer to the agent on which the force is acting + * @param force The force vector to draw + * @param label The label to apply to the force. + */ + void drawForce( const Agent * agt, const Vector2 & force, const std::string & label ); + + }; +} // namespace Helbing +#endif // __HELBING_AGENT_CONTEXT_H__ \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingConfig.h b/src/Plugins/AgtHelbing/HelbingConfig.h new file mode 100644 index 00000000..3b598313 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HelbingConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __HELBING_CONFIG_H__ +#define __HELBING_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( HELBING_STATICLIB ) + #define HELBING_API + #else + #if defined( HELBING_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define HELBING_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define HELBING_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( HELBING_STATICLIB ) + #define HELBING_API + #else + #if defined( HELBING_EXPORT ) + #define HELBING_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define HELBING_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __HELBING_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingDBEntry.cpp b/src/Plugins/AgtHelbing/HelbingDBEntry.cpp new file mode 100644 index 00000000..deae278e --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingDBEntry.cpp @@ -0,0 +1,89 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HelbingDBEntry.h" +#include "HelbingSimulator.h" +#include "SimulatorDB.h" +#include "HelbingAgentContext.h" +#include "HelbingInitializer.h" +#include "SimSystem.h" + +namespace Helbing { + ///////////////////////////////////////////////////////////////////////////// + // Implementation of Helbing::DBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Simulator based on Helbing et al. 2000 pedestrian model"; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on Helbing et al. 2000 pedestrian model\n" + "\tThe model is based on Dirk Helbing's 2000 paper.\n" + "\tOriginally designed for evacuation scenarios, it includes\n" + "\tthe contact and friction forces between agents."; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "Helbing 2000"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + BaseAgentContext * DBEntry::contextFromSystem( SimSystem * system ) { + return new AgentContext( system->getVisAgents(), (unsigned int)system->getAgentCount() ); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// + +} // namespace Helbing diff --git a/src/Plugins/AgtHelbing/HelbingDBEntry.h b/src/Plugins/AgtHelbing/HelbingDBEntry.h new file mode 100644 index 00000000..1220cad9 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingDBEntry.h @@ -0,0 +1,132 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HelbingDBEntry.h + * @brief The simulator database entry for the Helbing 2000 pedestrian model. + */ + +#ifndef __HELBING_DB_ENTRY_H__ +#define __HELBING_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "Helbing.h" + +using namespace Menge; + +namespace Helbing { + /*! + * @brief The simulator database entry for the Helbing 2000 simulator. + */ + class DBEntry : public SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "helbing"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + + protected: + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * If the provided system is not, in fact, a pointer to a SimSystem for the + * appropriate simulator type, this function will report failure. Furthermore, + * the default implementation is to return a BaseAgentContext. If the + * simulator comes with a novel context, this function should be overridden + * in the derived SimulatorDBEntry. + * + * @param system The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntryBase::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. If the system is of + * the wrong type (or if there is any other problem), NULL is returned. + */ + virtual BaseAgentContext * contextFromSystem( SimSystem * system ); + }; +} // namespace Helbing + +#endif // __HELBING_DB_ENTRY_H__ \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingInitializer.cpp b/src/Plugins/AgtHelbing/HelbingInitializer.cpp new file mode 100644 index 00000000..fda92d22 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingInitializer.cpp @@ -0,0 +1,128 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HelbingInitializer.h" +#include "HelbingAgent.h" +#include "Math/RandGenerator.h" + +namespace Helbing { + //////////////////////////////////////////////////////////////// + // Implementation of Helbing::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float MASS = 80.f; ///< The agent's default mass. + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Agents::AgentInitializer() { + _mass = new ConstFloatGenerator( MASS ); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init) : Agents::AgentInitializer(init) { + _mass = init._mass->copy(); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _mass; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_mass = _mass->getValue(); + return Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "Helbing" ) || Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + ParseResult result = IGNORED; + if ( paramName == "mass" ) { + result = constFloatGenerator( _mass, value ); + } + + if ( result == FAILURE ) { + logger << Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + ParseResult result = IGNORED; + if ( propName == "mass" ) { + result = getFloatGenerator( _mass, node ); + } + + if ( result == FAILURE ) { + logger << Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _mass ) delete _mass; + _mass = new ConstFloatGenerator( MASS ); + Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace Helbing diff --git a/src/Plugins/AgtHelbing/HelbingInitializer.h b/src/Plugins/AgtHelbing/HelbingInitializer.h new file mode 100644 index 00000000..6fef3e8d --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingInitializer.h @@ -0,0 +1,169 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file HelbingInitializer.h + * @brief The AgentInitializer for the Helbing simulator. + */ +#ifndef __HELBING_INITIALIZER_H__ +#define __HELBING_INITIALIZER_H__ + +#include "AgentInitializer.h" + +using namespace Menge; + +namespace Helbing { + /*! + * @brief Class which determines the agent properties for each new Helbing agent. + */ + class AgentInitializer : public Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The initializer to copy values from + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `<Helbing>` + * parameter set. + * + * @param tagName The tag to test for relevancy. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given <Property .../> tag. + * + * As a pre-condition to this function, the XML node contains a <Property.../> + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief The mass of the agent. + */ + FloatGenerator * _mass; + }; +} // namespace Helbing + + +#endif // __HELBING_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Plugins/AgtHelbing/HelbingSimulator.cpp b/src/Plugins/AgtHelbing/HelbingSimulator.cpp new file mode 100644 index 00000000..e7b3888c --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingSimulator.cpp @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HelbingSimulator.h" +#include "Utils.h" + +namespace Helbing { + //////////////////////////////////////////////////////////////// + // Implementation of Helbing::Simulator + //////////////////////////////////////////////////////////////// + + // These values come directly from the Helbing 2000 paper + float Simulator::AGENT_SCALE = 2000.f; + float Simulator::OBST_SCALE = 2000.f; + float Simulator::REACTION_TIME = 0.5f; + float Simulator::BODY_FORCE = 1.2e5f; + float Simulator::FRICTION = 2.4e5f; + float Simulator::FORCE_DISTANCE = 0.08f; + + //////////////////////////////////////////////////////////////// + + bool Simulator::setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ) { + try { + if ( paramName == "agent_scale" ) { + AGENT_SCALE = toFloat( value ); + } else if ( paramName == "obstacle_scale" ) { + OBST_SCALE = toFloat( value ); + } else if ( paramName == "reaction_time" ) { + REACTION_TIME = toFloat( value ); + } else if ( paramName == "body_force" ) { + BODY_FORCE = toFloat( value ); + } else if ( paramName == "friction" ) { + FRICTION = toFloat( value ); + } else if ( paramName == "force_distance" ) { + FORCE_DISTANCE = toFloat( value ); + } else if ( ! Agents::SimulatorBase<Agent>::setExpParam( paramName, value ) ) { + // Simulator base didn't recognize the parameter either + return false; + } + } catch ( UtilException ) { + throw Agents::XMLParamException( std::string( "Helbing parameter \"") + paramName + std::string("\" value couldn't be converted to the correct type. Found the value: " ) + value ); + } + return true; + } +} //namespace Helbing diff --git a/src/Plugins/AgtHelbing/HelbingSimulator.h b/src/Plugins/AgtHelbing/HelbingSimulator.h new file mode 100644 index 00000000..17539388 --- /dev/null +++ b/src/Plugins/AgtHelbing/HelbingSimulator.h @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __HELBING_SIMULATOR_H__ +#define __HELBING_SIMULATOR_H__ + +/*! + * @file HelbingSimulator.h + * @brief Contains the Helbing::Simulator class + * Implements Helbing's 2000 pedestrian model + */ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "HelbingAgent.h" + +using namespace Menge; + +/*! + * @namespace Helbing + * @brief The namespace for the Helbing pedestrian model. + * This is a model based on the model proposed in the + * Helbing et al., 2000 paper. + */ +namespace Helbing { + /*! + * @brief Defines the simulator operating on a Helbing::Agent. + */ + class Simulator : public Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator(): Agents::SimulatorBase< Agent >() {} + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * @param tagName the name of the considered tag + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return tagName == "Helbing"; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns whether or not parameters were successfully set + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ); + + protected: + friend class Agent; + /*! + * @brief The magnitude of the inter-agent repulsion forces + */ + static float AGENT_SCALE; + + /*! + * @brief The magnitude of the agent-obstacle repulsion forces + */ + static float OBST_SCALE; + + /*! + * @brief The reaction time used to define the driving force + */ + static float REACTION_TIME; + + /*! + * @brief The magnitude of the body force applied when agents collide + */ + static float BODY_FORCE; + + /*! + * @brief The magnitude of the friction force applied when agents collide + */ + static float FRICTION; + + /*! + * @brief The the fall-off distance of repulsive forces + */ + static float FORCE_DISTANCE; + }; +} // namespace Helbing +#endif // __HELBING_SIMULATOR_H__ \ No newline at end of file diff --git a/src/Plugins/AgtJohansson/Johansson.cpp b/src/Plugins/AgtJohansson/Johansson.cpp new file mode 100644 index 00000000..44ed67bd --- /dev/null +++ b/src/Plugins/AgtJohansson/Johansson.cpp @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Johansson.cpp + * @brief Plugin for Johansson 2007 pedestrian. + */ + +#include "JohanssonConfig.h" +#include "JohanssonDBEntry.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" JOHANSSON_API const char * getName() { + return "Johansson 2007 Pedestrian Model"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" JOHANSSON_API const char * getDescription() { + return "A pedestran plugin based on the model proposed in 2007 by Johansson et al."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" JOHANSSON_API void registerPlugin( PluginEngine * engine ) { + engine->registerModelDBEntry( new Johansson::DBEntry() ); +} + diff --git a/src/Plugins/AgtJohansson/Johansson.h b/src/Plugins/AgtJohansson/Johansson.h new file mode 100644 index 00000000..f715c0d8 --- /dev/null +++ b/src/Plugins/AgtJohansson/Johansson.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Johansson.h + * @brief Collection of Johansson 2007 Agent and Simulator. + */ + +#ifndef __JOHANSSON_H__ +#define __JOHANSSON_H__ + +#include "JohanssonAgent.h" +#include "JohanssonSimulator.h" + +#endif //__JOHANSSON_H__ \ No newline at end of file diff --git a/src/Plugins/AgtJohansson/JohanssonAgent.cpp b/src/Plugins/AgtJohansson/JohanssonAgent.cpp new file mode 100644 index 00000000..98f8e44a --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonAgent.cpp @@ -0,0 +1,120 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "JohanssonAgent.h" +#include "JohanssonSimulator.h" + +namespace Johansson { + //////////////////////////////////////////////////////////////// + // Implementation of Johansson::Agent + //////////////////////////////////////////////////////////////// + // direction weight value comes from Johansson's 2007 paper + Agent::Agent(): Agents::BaseAgent(), _dirWeight(0.16f) { + } + + //////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + //////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + const float TAU = Simulator::REACTION_TIME; + const float STEP_TIME = Simulator::STRIDE_TIME; + float B = Simulator::FORCE_DISTANCE; + + // driving force + Vector2 force( ( _velPref.getPreferredVel() - _vel ) / TAU ); + // agent forces + float A = Simulator::AGENT_SCALE; + for ( size_t i = 0; i < _nearAgents.size(); ++i ) { + const Agents::BaseAgent * otherBase = _nearAgents[i].agent; + const Agent * const other = static_cast< const Agent *>( otherBase ); + + Vector2 relPos = _pos - other->_pos; + float dist = abs( relPos ); + Vector2 relDir = relPos / dist; + // directional weight of force + + float cosTheta = relDir * _orient; + float magnitude = A * ( _dirWeight + (1.f - _dirWeight) * ( 1 + cosTheta ) * 0.5f ); + + // elliptical term + Vector2 stepOffset = other->_vel * STEP_TIME; + Vector2 relPosOffset = relPos - stepOffset; + float relPosOffsetDist = abs( relPosOffset ); + float term1 = dist + relPosOffsetDist; + float offsetDistSq = absSq( stepOffset ); + float b = 0.5f * sqrtf( term1 * term1 - offsetDistSq ); + float twoB = 2.f * b; + // Extra magnitude scaling term + magnitude *= term1 / twoB; + magnitude *= expf( -b / B ); + // Force direction + Vector2 forceDir = 0.5f * ( relDir + ( relPosOffset / relPosOffsetDist ) ); + force += magnitude * forceDir; + } + + // wall forces + A = Simulator::OBST_SCALE; + for ( size_t i = 0; i < _nearObstacles.size(); ++i ) { + Vector2 nearPt; // set by distanceSqToPoint + float distSq; // set by distanceSqToPoint + if ( _nearObstacles[ i ].obstacle->distanceSqToPoint( _pos, nearPt, distSq ) == Agents::Obstacle::LAST ) continue; + float dist = sqrtf( distSq ); + + Vector2 relPos = _pos - nearPt; + Vector2 relDir = relPos / dist; + // directional weight of force + + float cosTheta = relDir * _orient; + // NOTE: Below I have 1 - cosTheta instead of 1 + cosTheta + // The reason is that I have relDir defined in the opposite direction + float magnitude = A * ( _dirWeight + (1.f - _dirWeight) * ( 1 - cosTheta ) * 0.5f ); + + // Assuming stationary wall - elliptical term goes to distance + magnitude *= expf( -dist / B ); + // Force direction is just relative direction (for stationary wall) + force += magnitude * relDir; + } + // assume unit mass! + _velNew = _vel + force * Simulator::TIME_STEP; + } + +} // namespace Johansson diff --git a/src/Plugins/AgtJohansson/JohanssonAgent.h b/src/Plugins/AgtJohansson/JohanssonAgent.h new file mode 100644 index 00000000..b9b75b9b --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonAgent.h @@ -0,0 +1,81 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file JohanssonAgent.h + * @brief Definition of Johansson 2007 agent. + */ + +#ifndef __JOHANSSON_AGENT_H__ +#define __JOHANSSON_AGENT_H__ + +#include "BaseAgent.h" + +using namespace Menge; + +namespace Johansson { + /*! + * @brief Definition of Johansson 2007 agent. + * + * A social-force agent model. This assumes that all agents + * have unit-weight. + */ + class Agent : public Agents::BaseAgent { + public: + /*! + * @brief Default constructor. + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief The directional weight - repulsive force depends on direction to agent + */ + float _dirWeight; + }; +} // namespace Johansson +#endif // __JOHANSSON_AGENT_H__ \ No newline at end of file diff --git a/src/Plugins/AgtJohansson/JohanssonConfig.h b/src/Plugins/AgtJohansson/JohanssonConfig.h new file mode 100644 index 00000000..83bb4765 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file JohanssonConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __JOHANSSON_CONFIG_H__ +#define __JOHANSSON_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( JOHANSSON_STATICLIB ) + #define JOHANSSON_API + #else + #if defined( JOHANSSON_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define JOHANSSON_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define JOHANSSON_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( JOHANSSON_STATICLIB ) + #define JOHANSSON_API + #else + #if defined( JOHANSSON_EXPORT ) + #define JOHANSSON_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define JOHANSSON_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __JOHANSSON_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/AgtJohansson/JohanssonDBEntry.cpp b/src/Plugins/AgtJohansson/JohanssonDBEntry.cpp new file mode 100644 index 00000000..ac772812 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonDBEntry.cpp @@ -0,0 +1,82 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "JohanssonDBEntry.h" +#include "JohanssonSimulator.h" +#include "SimulatorDB.h" +#include "JohanssonInitializer.h" + +namespace Johansson { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of JohanssonDBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Simulator based on Johansson et al. 2007 pedestrian model"; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on Johansson et al. 2007 pedestrian model\n" + "\tThe model is based on Anders Johansson's 2007 paper.\n" + "\tUses elliptical forces, anisotropic responses, and velocity to\n" + "\tcompute forces."; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "Johansson"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// +} // namespace Johansson + diff --git a/src/Plugins/AgtJohansson/JohanssonDBEntry.h b/src/Plugins/AgtJohansson/JohanssonDBEntry.h new file mode 100644 index 00000000..89d70980 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonDBEntry.h @@ -0,0 +1,114 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file JohanssonDBEntry.h + * @brief The simulator database entry for the Johansson 2007 pedestrian model. + */ + +#ifndef __JOHANSSON_DB_ENTRY_H__ +#define __JOHANSSON_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "Johansson.h" + +using namespace Menge; + +namespace Johansson { + + /*! + * @brief The simulator database entry for the Johansson 2007 simulator. + */ + class DBEntry : public SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "johansson"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + }; +} // namespace Johansson + +#endif // __JOHANSSON_DB_ENTRY_H__ diff --git a/src/Plugins/AgtJohansson/JohanssonInitializer.cpp b/src/Plugins/AgtJohansson/JohanssonInitializer.cpp new file mode 100644 index 00000000..160ac857 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonInitializer.cpp @@ -0,0 +1,130 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "JohanssonInitializer.h" +#include "JohanssonAgent.h" +#include "Math/RandGenerator.h" + +namespace Johansson { + //////////////////////////////////////////////////////////////// + // Implementation of Johansson::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float DIR_WEIGHT = 0.16f; ///< The default field-of-view weight. + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Agents::AgentInitializer() { + _dirWeight = new ConstFloatGenerator( DIR_WEIGHT ); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) : Agents::AgentInitializer(init) { + _dirWeight = init._dirWeight->copy(); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _dirWeight; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_dirWeight = _dirWeight->getValue(); + + return Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "Johansson" ) || Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + ParseResult result = IGNORED; + if ( paramName == "fov_weight" ) { + result = constFloatGenerator( _dirWeight, value ); + } + + if ( result == FAILURE ) { + logger << Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + ParseResult result = IGNORED; + if ( propName == "fov_weight" ) { + result = getFloatGenerator( _dirWeight, node ); + } + + if ( result == FAILURE ) { + logger << Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _dirWeight ) delete _dirWeight; + _dirWeight = new ConstFloatGenerator( DIR_WEIGHT ); + + Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace Johansson diff --git a/src/Plugins/AgtJohansson/JohanssonInitializer.h b/src/Plugins/AgtJohansson/JohanssonInitializer.h new file mode 100644 index 00000000..dce9f74c --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonInitializer.h @@ -0,0 +1,169 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file JohanssonInitializer.h + * @brief The AgentInitializer for the Johansson simulator. + */ +#ifndef __JOHANSSON_INITIALIZER_H__ +#define __JOHANSSON_INITIALIZER_H__ + +#include "AgentInitializer.h" + +using namespace Menge; + +namespace Johansson { + /*! + * @brief Class which determines the agent properties for each new Johansson agent. + */ + class AgentInitializer : public Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The initializer to copy values from + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `<Johansson>` + * parameter set. + * + * @param tagName The tag to test for relevancy. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given <Property .../> tag. + * + * As a pre-condition to this function, the XML node contains a <Property.../> + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief The directional weight - repulsive force depends on direction to agent + */ + FloatGenerator * _dirWeight; + }; +} // namespace Johansson + + +#endif // __JOHANSSON_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Plugins/AgtJohansson/JohanssonSimulator.cpp b/src/Plugins/AgtJohansson/JohanssonSimulator.cpp new file mode 100644 index 00000000..1dd24519 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonSimulator.cpp @@ -0,0 +1,77 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "JohanssonSimulator.h" +#include "Utils.h" + +namespace Johansson { + //////////////////////////////////////////////////////////////// + // Implementation of Johansson::Simulator + //////////////////////////////////////////////////////////////// + + // These values come directly from the Johansson 2007 paper + float Simulator::AGENT_SCALE = 0.11f; + float Simulator::OBST_SCALE = 0.11f; + float Simulator::REACTION_TIME = 0.5f; + float Simulator::FORCE_DISTANCE = 1.19f; // This is a HUGE value, but specified in the paper + float Simulator::STRIDE_TIME = 0.5f; + + //////////////////////////////////////////////////////////////// + + bool Simulator::setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ) { + try { + if ( paramName == "agent_scale" ) { + AGENT_SCALE = toFloat( value ); + } else if ( paramName == "obstacle_scale" ) { + OBST_SCALE = toFloat( value ); + } else if ( paramName == "reaction_time" ) { + REACTION_TIME = toFloat( value ); + } else if ( paramName == "stride_time" ) { + STRIDE_TIME = toFloat( value ); + } else if ( paramName == "force_distance" ) { + FORCE_DISTANCE = toFloat( value ); + } else if ( ! Agents::SimulatorBase<Agent>::setExpParam( paramName, value ) ) { + // Simulator base didn't recognize the parameter either + return false; + } + } catch ( UtilException ) { + throw Agents::XMLParamException( std::string( "Johansson parameter \"") + paramName + std::string("\" value couldn't be converted to the correct type. Found the value: " ) + value ); + } + return true; + } +} //namespace Johansson diff --git a/src/Plugins/AgtJohansson/JohanssonSimulator.h b/src/Plugins/AgtJohansson/JohanssonSimulator.h new file mode 100644 index 00000000..3428a9f7 --- /dev/null +++ b/src/Plugins/AgtJohansson/JohanssonSimulator.h @@ -0,0 +1,125 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __JOHANSSON_SIMULATOR_H__ +#define __JOHANSSON_SIMULATOR_H__ + +/*! + * @file JohanssonSimulator.h + * @brief Contains the Johansson::Simulator class + * Implements Johansson's 2007 pedestrian model + */ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "JohanssonAgent.h" + +using namespace Menge; + +/*! + * @namespace Johansson + * @brief Contains the specification of the pedestrian model + * from the Johansson et al., 2007 paper. + */ +namespace Johansson { + /*! + * @brief Defines the simulator operating on a Johansson::Agent. + */ + class Simulator : public Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator(): Agents::SimulatorBase< Agent >() {} + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * @param tagName the name of the considered tag + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return tagName == "Johansson"; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns whether or not parameters were successfully set + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ); + + protected: + friend class Agent; + /*! + * @brief The magnitude of the inter-agent repulsion forces + */ + static float AGENT_SCALE; + + /*! + * @brief The magnitude of the agent-obstacle repulsion forces + */ + static float OBST_SCALE; + + /*! + * @brief The reaction time used to define the driving force + */ + static float REACTION_TIME; + + /*! + * @brief The the fall-off distance of repulsive forces + */ + static float FORCE_DISTANCE; + + /*! + * @brief The time of a pedestrian step + */ + static float STRIDE_TIME; + }; +} // namespace Johansson + +#endif // __JOHANSSON_SIMULATOR_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/Karamouzas.cpp b/src/Plugins/AgtKaramouzas/Karamouzas.cpp new file mode 100644 index 00000000..0f09cae6 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/Karamouzas.cpp @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Karamouzas.cpp + * @brief Plugin for orca pedestrian. + */ + +#include "KaramouzasConfig.h" +#include "KaramouzasDBEntry.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" KARAMOUZAS_API const char * getName() { + return "Karamouzas 2009 Pedestrian Model"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" KARAMOUZAS_API const char * getDescription() { + return "A pedestran plugin based on the model proposed in 2009 by Karamouzas et al."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" KARAMOUZAS_API void registerPlugin( PluginEngine * engine ) { + engine->registerModelDBEntry( new Karamouzas::DBEntry() ); +} + diff --git a/src/Plugins/AgtKaramouzas/Karamouzas.h b/src/Plugins/AgtKaramouzas/Karamouzas.h new file mode 100644 index 00000000..6c1d5781 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/Karamouzas.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Karamouzas.h + * @brief Collection of Karamouzas 2009 Agent and Simulator. + */ + +#ifndef __KARAMOUZAS_H__ +#define __KARAMOUZAS_H__ + +#include "KaramouzasAgent.h" +#include "KaramouzasSimulator.h" + +#endif // __KARAMOUZAS_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/KaramouzasAgent.cpp b/src/Plugins/AgtKaramouzas/KaramouzasAgent.cpp new file mode 100644 index 00000000..d23fba05 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasAgent.cpp @@ -0,0 +1,184 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "KaramouzasAgent.h" +#include "KaramouzasSimulator.h" +#include "Math/geomQuery.h" +#include <list> + +namespace Karamouzas { + //////////////////////////////////////////////////////////////// + // Implementation of Karamouzas::Agent + //////////////////////////////////////////////////////////////// + + Agent::Agent(): Agents::BaseAgent() { + _perSpace = 1.f; + _anticipation = 3.f; + } + + //////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + //////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + const float EPSILON = 0.01f; // this eps from Ioannis + const float FOV = Simulator::COS_FOV_ANGLE; + + Vector2 force( ( _velPref.getPreferredVel() - _vel ) / Simulator::REACTION_TIME ); + const float SAFE_DIST = Simulator::WALL_DISTANCE + _radius; + const float SAFE_DIST2 = SAFE_DIST * SAFE_DIST; + for ( size_t o = 0; o < _nearObstacles.size(); ++o ) { + // TODO: Interaction with obstacles is, currently, defined strictly + // by COLLISIONS. Only if I'm going to collide with an obstacle is + // a force applied. This may be too naive. + // I'll have to investigate this. + const Agents::Obstacle * obst = _nearObstacles[ o ].obstacle; + Vector2 nearPt; // set by distanceSqToPoint + float sqDist; // set by distanceSqToPoint + if ( obst->distanceSqToPoint( _pos, nearPt, sqDist ) == Agents::Obstacle::LAST ) continue; + if ( SAFE_DIST2 > sqDist ) { + // A repulsive force is actually possible + float dist = sqrtf( sqDist ); + float num = SAFE_DIST - dist; + float distMradius = ( dist - _radius ) < EPSILON ? EPSILON : dist - _radius; + float denom = powf( distMradius, Simulator::WALL_STEEPNESS ); + Vector2 dir = norm( _pos - nearPt ); + float mag = num / denom; + force += dir * mag; + } + } + + Vector2 desVel = _vel + force * Simulator::TIME_STEP; + float desSpeed = abs( desVel ); + force.set( 0.f, 0.f ); +//#if 0 +// // iteratively evaluate neighbors +//#else + // Weight all neighbors + bool colliding = false; + int collidingCount = Simulator::COLLIDING_COUNT; + bool VERBOSE = false; // _id == 1; + if ( VERBOSE ) std::cout << "Agent " << _id << "\n"; + float totalTime = 1.f; + std::list< std::pair< float, const Agent * > > collidingSet; + for ( size_t j = 0; j < _nearAgents.size(); ++j ) { + const Agents::BaseAgent * otherBase = _nearAgents[j].agent; + const Agent * const other = static_cast< const Agent *>( otherBase ); + float circRadius = _perSpace + other->_radius; + Vector2 relVel = desVel - other->_vel; + Vector2 relPos = other->_pos - _pos; + + if ( absSq( relPos ) < circRadius * circRadius) { ///collision! + if (!colliding) { + colliding = true; + collidingSet.clear(); + } + collidingSet.push_back(std::pair< float, const Agent * >(.0f, other ) ); + if ( static_cast<int>(collidingSet.size()) > collidingCount ) ++collidingCount; + continue; + } + + // TODO: evalute field of view + // If relPos is not within the field of view around preferred direction, continue + Vector2 relDir = norm( relPos ); + if ( ( relDir * _orient ) < FOV ) continue; + float tc = rayCircleTTC( relVel, relPos, circRadius ); + if ( tc < _anticipation && !colliding ) { + if ( VERBOSE ) std::cout << "\tAgent " << other->_id << " t_c: " << tc << "\n"; + //totalTime += tc; + // insert into colliding set (in order) + std::list< std::pair< float, const Agent * > >::iterator itr = collidingSet.begin(); + while ( itr != collidingSet.end() && tc > itr->first ) ++itr; + collidingSet.insert( itr, std::pair< float, const Agent * >( tc, other ) ); + } + } + //if ( collidingSet.size() > 0 ) { + int count = 0; + std::list< std::pair< float, const Agent * > >::iterator itr = collidingSet.begin(); + for ( int i = 0; i < collidingCount; ++i, ++itr ) { + if ( itr == collidingSet.end() ) break; + const Agent * const other = itr->second; + float tc = itr->first; + // future positions + Vector2 myPos = _pos + desVel * tc; + Vector2 hisPos = other->_pos + other->_vel * tc; + Vector2 forceDir = myPos - hisPos; + //float futureDist = abs( forceDir ); + //forceDir /= futureDist; + //float D = desSpeed * tc + futureDist - _radius - other->_radius; + float fDist = abs( forceDir ); + forceDir /= fDist; + float collisionDist = fDist - _radius - other->_radius; + float D = std::max( desSpeed * tc + (collisionDist < 0 ? 0 : collisionDist), EPSILON ); + + // determine magnitude + + float mag; + if ( D < Simulator::D_MIN ) { + mag = Simulator::AGENT_FORCE * Simulator::D_MIN / D; + } else if ( D < Simulator::D_MID ) { + mag = Simulator::AGENT_FORCE; + } else if ( D < Simulator::D_MAX ) { + //D -= Simulator::D_MID; + //mag = D * Simulator::AGENT_FORCE / ( Simulator::D_MAX - Simulator::D_MID ) + Simulator::D_MID ; + mag = Simulator::AGENT_FORCE * ( Simulator::D_MAX - D ) / ( Simulator::D_MAX - Simulator::D_MID ) ; + } else { + continue; // magnitude is zero + } + float weight = pow( colliding ? 1.f : 0.8f, count++ ); + //float weight = ( totalTime - tc ) / totalTime; //1.f / ( tc * totalTime ); + if ( VERBOSE ) std::cout << "\tAgent " << other->_id << " magnitude: " << mag << " weight: " << weight << " total force: " << ( mag * weight ) << " D: " << D << "\n"; + force += forceDir * ( mag * weight ); + } + // Add some noise to avoid deadlocks and introduce variation + //float angle = rand() * 2.0f * M_PI / RAND_MAX; + float angle = rand() * 2.0f * 3.1415f / RAND_MAX; + float dist = rand() * 0.001f / RAND_MAX; + force += dist*Vector2(cos(angle), sin(angle)); + // do we need a drag force? + + // Cap the force to maxAccel + if (abs(force)> _maxAccel) force = norm( force ) * _maxAccel; + + _velNew = desVel + force * Simulator::TIME_STEP; // assumes unit mass + } + +} // namespace Karamouzas diff --git a/src/Plugins/AgtKaramouzas/KaramouzasAgent.h b/src/Plugins/AgtKaramouzas/KaramouzasAgent.h new file mode 100644 index 00000000..f5d5acac --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasAgent.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file KaramouzasAgent.h + * @brief Contains the Karamouzas::Agent class + * Implements Karamouzas's 2009 pedestrian model + * "A Predictive Collision Avoidance Model for Pedestrian Simulation" + */ + +#ifndef __KARAMOUZAS_AGENT_H__ +#define __KARAMOUZAS_AGENT_H__ + +#include "BaseAgent.h" + +using namespace Menge; + +namespace Karamouzas { + /*! + * @brief The agent definition for the Karamouzas 2009 agent. + */ + class Agent : public Agents::BaseAgent { + public: + /*! + * @brief A variant of the copy constructor. + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief The personal space (in meters) of the agent + */ + float _perSpace; + + /*! + * @brief The anticipation time (in seconds) of the agent + */ + float _anticipation; + + }; +} // namespace Karamouzas +#endif // __KARAMOUZAS_AGENT_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/KaramouzasConfig.h b/src/Plugins/AgtKaramouzas/KaramouzasConfig.h new file mode 100644 index 00000000..f3564d83 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file KaramouzasConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __KARAMOUZAS_CONFIG_H__ +#define __KARAMOUZAS_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( KARAMOUZAS_STATICLIB ) + #define KARAMOUZAS_API + #else + #if defined( KARAMOUZAS_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define KARAMOUZAS_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define KARAMOUZAS_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( KARAMOUZAS_STATICLIB ) + #define KARAMOUZAS_API + #else + #if defined( KARAMOUZAS_EXPORT ) + #define KARAMOUZAS_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define KARAMOUZAS_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __KARAMOUZAS_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.cpp b/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.cpp new file mode 100644 index 00000000..970489de --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.cpp @@ -0,0 +1,82 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "KaramouzasDBEntry.h" +#include "SimulatorDB.h" +#include "KaramouzasInitializer.h" + +namespace Karamouzas { + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of KaramouzasDBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Simulator based on Karamouzas's 2009 predictive collision pedestrian model"; + } + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on Karamouzas's 2009 predictive collision pedestrian model\n" + "\tThe model is based on Ioannis Karamouzas's 2009 paper.\n" + "\tI've changed the wall forces so that the direction isn't simply the wall normal\n" + "\tbut the direction from the nearest point on the wall to the agent.\n" + "\tI've also only implemented the superposition of forces (not the iterative algorithm)."; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "Karamouzas 2009"; + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// + +} // namespace Karamouzas diff --git a/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.h b/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.h new file mode 100644 index 00000000..8cec1d89 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasDBEntry.h @@ -0,0 +1,112 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file KaramouzasDBEntry.h + * @brief The simulator database entry for the Karamouzas 2009 pedestrian model. + */ + +#ifndef __KARAMOUZAS_DB_ENTRY_H__ +#define __KARAMOUZAS_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "Karamouzas.h" + +using namespace Menge; + +namespace Karamouzas { + /*! + * @brief The simulator database entry for the Karamouzas 2009 simulator. + */ + class DBEntry : public SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "karamouzas"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + }; +} // namespace Karamouzas +#endif // __KARAMOUZAS_DB_ENTRY_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/KaramouzasInitializer.cpp b/src/Plugins/AgtKaramouzas/KaramouzasInitializer.cpp new file mode 100644 index 00000000..aaa76a3d --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasInitializer.cpp @@ -0,0 +1,141 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "KaramouzasInitializer.h" +#include "KaramouzasAgent.h" +#include "Math/RandGenerator.h" + +namespace Karamouzas { + //////////////////////////////////////////////////////////////// + // Implementation of Karamouzas::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float PER_SPACE = 1.f; ///< The default personal space for the agent. + const float ANTICIPATION = 3.f; ///< The anticipation time of the agent. + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Agents::AgentInitializer() { + _perSpace = new ConstFloatGenerator( PER_SPACE ); + _anticipation = new ConstFloatGenerator( ANTICIPATION ); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) : Agents::AgentInitializer(init) { + _perSpace = init._perSpace->copy(); + _anticipation = init._anticipation->copy(); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _perSpace; + delete _anticipation; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_perSpace = _perSpace->getValue(); + a->_anticipation = _anticipation->getValue(); + + return Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "Karamouzas" ) || Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + ParseResult result = IGNORED; + if ( paramName == "personal_space" ) { + result = constFloatGenerator( _perSpace, value ); + } else if ( paramName == "anticipation" ) { + result = constFloatGenerator( _anticipation, value ); + } + + if ( result == FAILURE ) { + logger << Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + ParseResult result = IGNORED; + if ( propName == "personal_space" ) { + result = getFloatGenerator( _perSpace, node ); + } else if ( propName == "anticipation" ) { + result = getFloatGenerator( _anticipation, node ); + } + + if ( result == FAILURE ) { + logger << Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _perSpace ) delete _perSpace; + _perSpace = new ConstFloatGenerator( PER_SPACE ); + if ( _anticipation ) delete _anticipation; + _anticipation = new ConstFloatGenerator( ANTICIPATION ); + + Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace Karamouzas diff --git a/src/Plugins/AgtKaramouzas/KaramouzasInitializer.h b/src/Plugins/AgtKaramouzas/KaramouzasInitializer.h new file mode 100644 index 00000000..517ce82b --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasInitializer.h @@ -0,0 +1,175 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file KaramouzasInitializer.h + * @brief The AgentInitializer for the Karamouzas simulator. + */ +#ifndef __KARAMOUZAS_INITIALIZER_H__ +#define __KARAMOUZAS_INITIALIZER_H__ + +#include "AgentInitializer.h" + +using namespace Menge; + +namespace Karamouzas { + /*! + * @brief Class which determines the agent properties for each new Karamouzas agent. + */ + class AgentInitializer : public Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The initializer to copy values from + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `<Karamouzas>` + * parameter set. + * + * @param tagName The tag to test for relevancy. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given <Property .../> tag. + * + * As a pre-condition to this function, the XML node contains a <Property.../> + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief The personal space (in meters) of the agent + */ + FloatGenerator * _perSpace; + + /*! + * @brief The anticipation time (in seconds) of the agent + */ + FloatGenerator * _anticipation; + + }; +} // namespace Karamouzas + + +#endif // __KARAMOUZAS_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Plugins/AgtKaramouzas/KaramouzasSimulator.cpp b/src/Plugins/AgtKaramouzas/KaramouzasSimulator.cpp new file mode 100644 index 00000000..0a4ae3c6 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasSimulator.cpp @@ -0,0 +1,92 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "KaramouzasSimulator.h" +#include "Utils.h" + +namespace Karamouzas { + //////////////////////////////////////////////////////////////// + // Implementation of Karamouzas::Simulator + //////////////////////////////////////////////////////////////// + + // These values come directly from the Karamouzas paper + float Simulator::ORIENT_WEIGHT = 0.8f; + float Simulator::COS_FOV_ANGLE = cos( 100.f * DEG_TO_RAD ); // 100 degrees (200 total) + float Simulator::REACTION_TIME = 0.4f; + float Simulator::WALL_STEEPNESS = 2.f; + float Simulator::WALL_DISTANCE = 2.f; // 2 meters (from the author's email...seem's quite large.) + int Simulator::COLLIDING_COUNT = 5; // K most dangerous neighbors considered + float Simulator::D_MIN = 1.f; + float Simulator::D_MID = 8.f; + float Simulator::D_MAX = 10.f; + float Simulator::AGENT_FORCE = 3.f; // how many Newtons? + + //////////////////////////////////////////////////////////////// + + bool Simulator::setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ) { + try { + if ( paramName == "orient_weight" ) { + ORIENT_WEIGHT = toFloat( value ); + } else if ( paramName == "fov" ) { + COS_FOV_ANGLE = cos( 0.5f * toFloat( value ) * DEG_TO_RAD ); // convert degrees to radians - operate on half angle + } else if ( paramName == "reaction_time" ) { + REACTION_TIME = toFloat( value ); + } else if ( paramName == "wall_steepness" ) { + WALL_STEEPNESS = toFloat( value ); + } else if ( paramName == "wall_distance" ) { + WALL_DISTANCE = toFloat( value ); + } else if ( paramName == "colliding_count" ) { + COLLIDING_COUNT = toInt( value ); + } else if ( paramName == "d_min" ) { + D_MIN = toFloat( value ); + } else if ( paramName == "d_mid" ) { + D_MID = toFloat( value ); + } else if ( paramName == "d_max" ) { + D_MAX = toFloat( value ); + } else if ( paramName == "agent_force" ) { + AGENT_FORCE = toFloat( value ); + } else if ( ! Agents::SimulatorBase< Agent >::setExpParam( paramName, value ) ) { + // Simulator base didn't recognize the parameter either + return false; + } + } catch ( UtilException ) { + throw Agents::XMLParamException( std::string( "Karamouzas parameter \"") + paramName + std::string("\" value couldn't be converted to the correct type. Found the value: " ) + value ); + } + return true; + } +} //namespace Karamouzas diff --git a/src/Plugins/AgtKaramouzas/KaramouzasSimulator.h b/src/Plugins/AgtKaramouzas/KaramouzasSimulator.h new file mode 100644 index 00000000..d0d11624 --- /dev/null +++ b/src/Plugins/AgtKaramouzas/KaramouzasSimulator.h @@ -0,0 +1,153 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __KARAMOUZAS_SIMULATOR_H__ +#define __KARAMOUZAS_SIMULATOR_H__ + +/*! + * @file KaramouzasSimulator.h + * @brief Contains the Karamouzas::Simulator class + * Implements Karamouzas's 2009 pedestrian model + * "A Predictive Collision Avoidance Model for Pedestrian Simulation" + */ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "KaramouzasAgent.h" + +using namespace Menge; + +/*! + * @namespace Karamouzas + * @brief Contains the specification of the pedestrian model + * from the Karamouzas et al., 2009 paper. + */ +namespace Karamouzas { + /*! + * @brief Defines the simulator operating on a Karamouzas::Agent. + */ + class Simulator : public Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator(): Agents::SimulatorBase< Agent >() {} + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * @param tagName the name of the considered tag + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return tagName == "Karamouzas"; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns whether or not parameters were successfully set + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ); + + protected: + friend class Agent; + /*! + * @brief Agent orientation is a weighted average between preferred + * direction and actual direction. This is that weight + */ + static float ORIENT_WEIGHT; + + /*! + * @brief The half angle that defines the field of view around + * orientation + */ + static float COS_FOV_ANGLE; + + /*! + * @brief The reaction time used to define the driving force + */ + static float REACTION_TIME; + + /*! + * @brief The steepness that the wall forces fall off: K > 0 + */ + static float WALL_STEEPNESS; + + /*! + * @brief The safe distance agents prefer to keep from the walls + */ + static float WALL_DISTANCE; + + /*! + * @brief The number of agents considered in the colliding set + */ + static int COLLIDING_COUNT; + + /*! + * @brief The critical distance at which agent response force climbs. + */ + static float D_MIN; + + /*! + * @brief The distance at which a constant agent response force begins. + */ + static float D_MID; + + /*! + * @brief The distance at which there is no longer an agent response force. + */ + static float D_MAX; + + /*! + * @brief The level of response force in the constant region. + */ + static float AGENT_FORCE; + }; +} // namespace Karamouzas + +#endif // __KARAMOUZAS_SIMULATOR_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/Zanlungo.cpp b/src/Plugins/AgtZanlungo/Zanlungo.cpp new file mode 100644 index 00000000..2d88b840 --- /dev/null +++ b/src/Plugins/AgtZanlungo/Zanlungo.cpp @@ -0,0 +1,74 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Zanlungo.cpp + * @brief Plugin for Zanlungo pedestrian. + */ + +#include "ZanlungoConfig.h" +#include "ZanlungoDBEntry.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" ZANLUNGO_API const char * getName() { + return "Zanlungo Pedestrian Model"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" ZANLUNGO_API const char * getDescription() { + return "A pedestran plugin based on the model proposed in 2011 by Zanlungo et al."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" ZANLUNGO_API void registerPlugin( PluginEngine * engine ) { + engine->registerModelDBEntry( new Zanlungo::DBEntry() ); +} + diff --git a/src/Plugins/AgtZanlungo/Zanlungo.h b/src/Plugins/AgtZanlungo/Zanlungo.h new file mode 100644 index 00000000..d7ac38e7 --- /dev/null +++ b/src/Plugins/AgtZanlungo/Zanlungo.h @@ -0,0 +1,50 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Zanlungo.h + * @brief The definition of the Zanlungo pedestrian plug-in + */ + +#ifndef __ZANLUNGO_H__ +#define __ZANLUNGO_H__ + +#include "ZanlungoAgent.h" +#include "ZanlungoSimulator.h" + +#endif // __ZANLUNGO_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/ZanlungoAgent.cpp b/src/Plugins/AgtZanlungo/ZanlungoAgent.cpp new file mode 100644 index 00000000..66bb095a --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoAgent.cpp @@ -0,0 +1,283 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ZanlungoAgent.h" +#include "ZanlungoSimulator.h" +#include "Math/geomQuery.h" +#include "Math/consts.h" + +namespace Zanlungo { + //////////////////////////////////////////////////////////////// + // Implementation of Zanlungo::Agent + //////////////////////////////////////////////////////////////// + + Agent::Agent(): Agents::BaseAgent() { + _mass = 80.f; + } + + //////////////////////////////////////////////////////////////// + + Agent::~Agent() { + } + + //////////////////////////////////////////////////////////////// + + void Agent::computeNewVelocity() { + // 1. Compute T_i + float T_i; + bool interacts = computeTTI( T_i ); + + const float TAU = Simulator::REACTION_TIME; + Vector2 force( ( _velPref.getPreferredVel() - _vel ) * _mass / TAU ); + + if ( interacts ) { + // if T_i never got set, there are no interactions to do + const float SPEED = abs( _vel ); + const float B = Simulator::FORCE_DISTANCE; + //const float MAG = Simulator::AGENT_SCALE * SPEED / T_i; + for ( size_t j = 0; j < _nearAgents.size(); ++j ) { + // 2. Use T_i to compute the direction + const Agents::BaseAgent * otherBase = _nearAgents[j].agent; + const Agent * const other = static_cast< const Agent *>( otherBase ); + force += agentForce( other, T_i ); + } + // obstacles + Vector2 futurePos = _pos + _vel * T_i; + const float OBST_MAG = Simulator::OBST_SCALE * SPEED / T_i; + for ( size_t obs = 0; obs < _nearObstacles.size(); ++obs ) { + Vector2 nearPt; // set by call to distanceSqToPoint + float d2; // set by call to distanceSqToPoint + if ( _nearObstacles[ obs ].obstacle->distanceSqToPoint( futurePos, nearPt, d2 ) == Agents::Obstacle::LAST ) continue; + Vector2 D_ij = futurePos - nearPt; + float dist = abs( D_ij ); + D_ij /= dist; + dist -= _radius; + force += D_ij * ( OBST_MAG * expf( -dist / B ) ); + } + } + + Vector2 acc = force / _mass; + _velNew = _vel + acc * Simulator::TIME_STEP; + } + + //////////////////////////////////////////////////////////////// + + Vector2 Agent::agentForce( const Agent * other, float T_i ) const { + float D = Simulator::FORCE_DISTANCE; + // Right of way-dependent calculations + Vector2 myVel = _vel; + Vector2 hisVel = other->_vel; + float weight = 1.f - rightOfWayVel( hisVel, other->_velPref.getPreferredVel(), other->_priority, myVel ); + + const Vector2 relVel = myVel - hisVel; + + Vector2 futPos = _pos + myVel * T_i; + Vector2 otherFuturePos = other->_pos + hisVel * T_i; + Vector2 D_ij = futPos - otherFuturePos; + + // If the relative velocity is divergent do nothing + if ( D_ij * ( _vel - other->_vel ) > 0.f ) return Vector2(0.f,0.f); + float dist = abs( D_ij ); + D_ij /= dist; + if ( weight > 1.f ) { + // Other agent has right of way + float prefSpeed = other->_velPref.getSpeed(); + Vector2 perpDir; + bool interpolate = true; + if ( prefSpeed < 0.0001f ) { + // he wants to be stationary, accelerate perpinduclarly to displacement + Vector2 currRelPos = _pos - other->_pos; + perpDir.set( -currRelPos.y(), currRelPos.x() ); + if ( perpDir * _vel < 0.f ) perpDir.negate(); + } else { + // He's moving somewhere, accelerate perpindicularly to his preferred direction + // of travel. + const Vector2 prefDir( other->_velPref.getPreferred() ); + if ( prefDir * D_ij > 0.f ) { + perpDir.set( -prefDir.y(), prefDir.x() ); // perpendicular to preferred velocity + if ( perpDir * D_ij < 0.f ) perpDir.negate(); + } else { + interpolate = false; + } + } + // spherical linear interpolation + if ( interpolate ) { + float sinTheta = det( perpDir, D_ij ); + if ( sinTheta < 0.f ) { + sinTheta = -sinTheta; + } + if ( sinTheta > 1.f ) { + sinTheta = 1.f; // clean up numerical error arising from determinant + } + D_ij.set( slerp( weight - 1.f, D_ij, perpDir, sinTheta ) ); + } + } + dist -= ( _radius + other->_radius ); + float magnitude = weight * Simulator::AGENT_SCALE * abs( _vel - other->_vel ) / T_i; + const float MAX_FORCE = 1e15f; + if ( magnitude >= MAX_FORCE ) { + magnitude = MAX_FORCE; + } + //float magnitude = weight * Simulator::AGENT_SCALE * abs( myVel - hisVel ) / T_i; + // 3. Compute the force + return D_ij * ( magnitude * expf( -dist / D ) ); + } + + //////////////////////////////////////////////////////////////// + + bool Agent::computeTTI( float & T_i ) const { + const float COS_FOV = -0.8f;// cos( HALFPI );// cos( PI / 4.f ); // + bool interacts = false; + T_i = INFTY; + //std::cout << "\n"; +#define COLLIDE_PRIORITY +#ifdef COLLIDE_PRIORITY + float t_collision = T_i; +#endif + for ( size_t j = 0; j < _nearAgents.size(); ++j ) { + const Agents::BaseAgent * otherBase = _nearAgents[j].agent; + const Agent * const other = static_cast< const Agent *>( otherBase ); + + // Right of way-dependent calculations + Vector2 myVel = _vel; + Vector2 hisVel = other->_vel; + rightOfWayVel( hisVel, other->_velPref.getPreferredVel(), other->_priority, myVel ); + + const Vector2 relVel = myVel - hisVel; + Vector2 relPos = _pos - other->_pos; +// This define determines if additional prediction code is executed +// The original zanlungo model does not include performing exact collisions +// between disks. It simply estimates the time to interaction based on +// projection of center on preferred velocity. +// This define includes a precise test of ray-circle intersection to test +// to see if the relative velocity intersects the minkowski sum of this +// agent with its neighbor. It makes the respones far more robust. +#define PRECISE +#ifdef PRECISE + float circRadius = _radius + other->_radius; + // first test to see if there's an actual collision imminent + float contactT = rayCircleTTC( relVel, -relPos, circRadius ); + //std::cout << "\tColliding with " << other->_id << " at " << contactT << "\n"; +#ifdef COLLIDE_PRIORITY + if ( contactT < t_collision ) { + // the ray intersects the circle -- actual collision is possible + t_collision = contactT; + interacts = true; + } else if ( t_collision == INFTY ) { +#else + if ( contactT < T_i ) { + // the ray intersects the circle -- actual collision is possible + T_i = contactT; + interacts = true; + } else { +#endif // COLLIDE_PRIORITY +#endif // PRECISE + // no collision possible, see if getting close is possible +#ifdef ZANLUNGO_FOV + float dist = abs( relPos ); + float relSpeed = abs( relVel ); + // This is the angle between relative position and ORIENTATION + float cosTheta = -( relPos * _orient ) / dist; + if ( cosTheta >= COS_FOV ) { + // This is the angle between relative position and relative velocity + cosTheta = relPos * relVel / ( -dist * relSpeed ); + float t_ij = cosTheta * dist / relSpeed; + //std::cout << "\tApproaching " << other->_id << " at " << t_ij << "\n"; + if ( t_ij < T_i ) { + T_i = t_ij; + interacts = true; + } + } +#else + // note: relPos points from other agent to this agent, so they need to point in OPPOSITE directions for convergence + float dp = -( relPos * relVel ); + if ( dp > 0.f ) { + float t_ij = dp / absSq( relVel ); + if ( t_ij < T_i ) { + T_i = t_ij; + interacts = true; + } + } +#endif +#ifdef PRECISE + } +#endif + } + // Compute time to interaction for obstacles + for ( size_t obs = 0; obs < _nearObstacles.size(); ++obs ) { + // TODO: Interaction with obstacles is, currently, defined strictly + // by COLLISIONS. Only if I'm going to collide with an obstacle is + // a force applied. This may be too naive. + // I'll have to investigate this. + float t = _nearObstacles[ obs ].obstacle->circleIntersection( _vel, _pos, _radius ); + if ( t < T_i ) { + T_i = t; + interacts = true; + } + } +#ifdef COLLIDE_PRIORITY + if ( t_collision < INFTY ) T_i = t_collision; +#endif + if ( T_i < Simulator::TIME_STEP ) { + T_i = Simulator::TIME_STEP; + } + + return interacts; + } + + //////////////////////////////////////////////////////////////// + + float Agent::rightOfWayVel( Vector2 & otherVel, const Vector2 & otherPrefVel, float otherPriority, Vector2 & vel ) const { + float rightOfWay = _priority - otherPriority; + rightOfWay = ( rightOfWay < -1.f ) ? -1.f : (rightOfWay > 1.f) ? 1.f : rightOfWay; + if ( rightOfWay < 0.f ) { + float R2 = sqrtf( -rightOfWay ); //rightOfWay * rightOfWay; // -rightOfWay; // + vel = _vel; + otherVel += R2 * ( otherPrefVel - otherVel ); + return -R2; + } else if ( rightOfWay > 0.f ) { + float R2 = sqrtf( rightOfWay ); //rightOfWay * rightOfWay; // rightOfWay; // + vel = _vel + R2 * ( _velPref.getPreferredVel() - _vel ); + return R2; + } else { + vel = _vel; + return 0.f; + } + } + +} // namespace Zanlungo diff --git a/src/Plugins/AgtZanlungo/ZanlungoAgent.h b/src/Plugins/AgtZanlungo/ZanlungoAgent.h new file mode 100644 index 00000000..3fedd598 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoAgent.h @@ -0,0 +1,118 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ZanlungoAgent.h + * @brief Contains the Zanlungo::Agent class + * Implements Zanlungo's 2011 pedestrian model + * "Social Force Model with Explicit Collision Prediction" + */ + +#ifndef __ZANLUNGO_AGENT_H__ +#define __ZANLUNGO_AGENT_H__ + +#include "BaseAgent.h" + +using namespace Menge; + +namespace Zanlungo { + /*! + * @brief Agent definition for the Zanlungo pedestrian model. + */ + class Agent : public Agents::BaseAgent { + public: + /*! + * @brief Default constructor. + */ + Agent(); + + /*! + * @brief Destroys this agent instance. + */ + ~Agent(); + + /*! + * @brief Computes the time to interaction + * @param tti The time to interaction. Call by reference means + * that this value is set to the time to interaction + * @returns A boolean reporting if there is interaction. True if there + * is interaction, false otherwise. + */ + bool computeTTI( float & tti ) const; + + /*! + * @brief Compute the force due to another agent + * @param other A pointer to a neighboring agent + * @param T_i The time to interaction + * @returns The force imparted by the other agent on this agent + */ + Vector2 agentForce( const Agent * other, float T_i ) const; + + /*! + * @brief Computes the new velocity of this agent. + */ + void computeNewVelocity(); + + /*! + * @brief Reports the field of view for the agent + */ + inline float getFOV() const { return 3.14159265f /* * 0.5*/; }// 90 degrees + + /*! + * @brief Computes the velocities based on right of way + * @param otherVel The other agent's current velocity. + * The right-of-way-relative other velocity + * will be set in this variable. + * @param otherPrefVel The other agent's preferred velocity. + * @param otherPriority The other agent's priority value + * @param vel This agent's right-of-way-relative velocity + * will be placed in this variable. + * @returns The signed right of way value. (Negative implies other has + * right of way, positive implies this agent has right of way.) + */ + float rightOfWayVel( Vector2 & otherVel, const Vector2 & otherPrefVel, float otherPriority, Vector2 & vel ) const; + + /*! + * @brief The mass of the agent + */ + float _mass; + + }; +} // namespace Zanlungo + +#endif // __ZANLUNGO_AGENT_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/ZanlungoAgentContext.cpp b/src/Plugins/AgtZanlungo/ZanlungoAgentContext.cpp new file mode 100644 index 00000000..db277d0b --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoAgentContext.cpp @@ -0,0 +1,315 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ZanlungoAgentContext.h" +#include "ZanlungoAgent.h" +#include "VisAgent.h" +#include "shapes.h" +#include <iomanip> + +namespace Zanlungo { + + //////////////////////////////////////////////////////////////// + // Implementation of ZanlungoAgentContext + //////////////////////////////////////////////////////////////// + + AgentContext::AgentContext( VisAgent ** agents, unsigned int agtCount ):BaseAgentContext(agents,agtCount), _showTTI(false), _ttiObject(0), _showForce(false) { + } + + //////////////////////////////////////////////////////////////// + + SceneGraph::ContextResult AgentContext::handleKeyboard( SDL_Event & e ) { + SceneGraph::ContextResult result = BaseAgentContext::handleKeyboard( e ); + if ( !result.isHandled() ) { + SDLMod mods = e.key.keysym.mod; + bool hasCtrl = ( mods & KMOD_CTRL ) > 0; + bool hasAlt = ( mods & KMOD_ALT ) > 0; + bool hasShift = ( mods & KMOD_SHIFT ) > 0; + bool noMods = !(hasCtrl || hasAlt || hasShift ); + if ( e.type == SDL_KEYDOWN ) { + if ( noMods ) { + if ( e.key.keysym.sym == SDLK_i ) { + _showTTI = !_showTTI; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_f ) { + _showForce = !_showForce; + result.set( true, true ); + } else if ( e.key.keysym.sym == SDLK_UP ) { + if ( ( _showTTI || _showForce ) && _selected ) { + const Agent * agt = dynamic_cast< Agent * >( _selected->getAgent() ); + int NBRS = (int)agt->_nearAgents.size(); + int OBST = (int)agt->_nearObstacles.size(); + if ( NBRS | OBST ) { + ++_ttiObject; + if ( _ttiObject > NBRS ) { + if ( OBST ) { + _ttiObject = -OBST; + } else { + _ttiObject = 0; + } + } + result.set( true, true ); + } + } + } else if ( e.key.keysym.sym == SDLK_DOWN ) { + if ( ( _showTTI || _showForce ) && _selected ) { + const Agent * agt = dynamic_cast< Agent * >( _selected->getAgent() ); + int NBRS = (int)agt->_nearAgents.size(); + int OBST = (int)agt->_nearObstacles.size(); + if ( NBRS | OBST ) { + --_ttiObject; + if ( _ttiObject < -OBST ) { + if ( NBRS ) { + _ttiObject = NBRS; + } else { + _ttiObject = -1; + } + } + result.set( true, true ); + } + } + } + } + } + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::draw3DGL( bool select ) { + BaseAgentContext::draw3DGL( select ); + if ( !select && _selected ) { + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + glDepthMask( GL_FALSE ); + const Agent * agt = dynamic_cast< Agent * >( _selected->getAgent() ); + drawTTI( agt ); + drawForce( agt ); + drawOrientationFan( agt ); + glPopAttrib(); + } + } + + //////////////////////////////////////////////////////////////// + + std::string AgentContext::agentText( const Agents::BaseAgent * agent ) const { + const Agent * agt = dynamic_cast< const Agent * >( agent ); + std::string m = BaseAgentContext::agentText( agt ); + + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + + ss << "\n_________________________"; + ss << "\nTime to (I)nteraction"; + if ( _showTTI && _selected ) { + float TTI; + if ( agt->computeTTI( TTI ) ) { + ss << ": " << TTI << " s "; + } else { + ss << ": infinite"; + } + } + ss << "\nDraw (F)orces"; + if ( ( _showTTI || _showForce ) && _selected ) { + ss << "\n (up/down arrow to select single)"; + } + return m + ss.str(); + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::drawTTI( const Agent * agt ) { + if ( _showTTI && _selected ) { + float TTI; + if ( agt->computeTTI( TTI ) ) { + glPushMatrix(); + // Draw the future position of THIS agent + Vector2 futurePos = agt->_pos + agt->_vel * TTI; + glColor4f( 1.f, 1.f, 1.f, 0.5f ); + glBegin( GL_LINES ); + glVertex3f( futurePos.x(), Y, futurePos.y() ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glEnd(); + glPushMatrix(); + glTranslatef( futurePos.x(), Y, futurePos.y() ); + SceneGraph::Circle::drawCircle( agt->_radius, 1.f, 1.f, 1.f, 0.75f, GL_LINE ); + glPopMatrix(); + + if ( _ttiObject == 0 ) { + // draw all the future positions of the agents + const int NBRS = (int)agt->_nearAgents.size(); + for ( int i = 0; i < NBRS; ++i ) { + // future position + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( i ) ); + Vector2 futurePos2 = other->_pos + other->_vel * TTI; + glColor3f( 1.f, 0.f, 0.f ); + glBegin( GL_LINES ); + glVertex3f( futurePos2.x(), Y, futurePos2.y() ); + glVertex3f( other->_pos.x(), Y, other->_pos.y() ); + glEnd(); + glPushMatrix(); + glTranslatef( futurePos2.x(), Y, futurePos2.y() ); + SceneGraph::Circle::drawCircle( other->_radius, 1.f, 0.f, 0.f, 0.75f, GL_LINE ); + glPopMatrix(); + } + } else if ( _ttiObject > 0 ) { + // Draw the future position of _ttiObject + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( _ttiObject - 1 ) ); + Vector2 futurePos2 = other->_pos + other->_vel * TTI; + glColor3f( 1.f, 0.f, 0.f ); + glBegin( GL_LINES ); + glVertex3f( futurePos2.x(), Y, futurePos2.y() ); + glVertex3f( other->_pos.x(), Y, other->_pos.y() ); + glEnd(); + glPushMatrix(); + glTranslatef( futurePos2.x(), Y, futurePos2.y() ); + SceneGraph::Circle::drawCircle( other->_radius, 1.f, 0.f, 0.f, 0.75f, GL_LINE ); + glPopMatrix(); + + } else if ( _ttiObject < 0 ){ + // draw obstacle + } + glPopMatrix(); + } + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::drawForce( const Agent * agt ) { + if ( _showForce && _selected ) { + float TTI; + if ( agt->computeTTI( TTI ) ) { // returns true if there are interactions + glPushMatrix(); + if ( _ttiObject == 0 ) { + // draw all the future positions of the agents + const int NBRS = (int)agt->_nearAgents.size(); + for ( int i = 0; i < NBRS; ++i ) { + // future position + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( i ) ); + singleAgentForce( agt, other, TTI ); + } + } else if ( _ttiObject > 0 ) { + const Agent * other = static_cast< const Agent *>( agt->getNeighbor( _ttiObject - 1 ) ); + singleAgentForce( agt, other, TTI ); + } else if ( _ttiObject < 0 ){ + // draw obstacle + } + glPopMatrix(); + } + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::singleAgentForce( const Agent * agt, const Agent * other, float TTI ) { + // This is for printing force magnitude and source + SceneGraph::TextWriter * writer = SceneGraph::TextWriter::Instance(); + // Get screen coordintes of source and force + double modViewMat[16], projMat[16]; + int viewMat[4]; + // NOTE: I'm doing this for each neighboring force. That's inefficient + // HOWEVER, the expectation is that it is only done for one agent at a time + // so, the inefficiency is negligble. + glGetDoublev( GL_MODELVIEW_MATRIX, &modViewMat[0] ); + glGetDoublev( GL_PROJECTION_MATRIX, &projMat[0] ); + glGetIntegerv( GL_VIEWPORT, &viewMat[0] ); + + Vector2 force = agt->agentForce( other, TTI ); + float forceMag = abs( force ); + if ( forceMag > 0.5f ) { + glColor4f( 1.f, 1.f, 1.f, 1.f ); + Vector2 forceEnd = agt->_pos + force; + glBegin( GL_LINES ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + glVertex3f( forceEnd.x(), Y, forceEnd.y() ); + glEnd(); + // annotate illustration + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 ); + ss << other->_id; + // Label the source agent + writeAlignedText( ss.str(), other->_pos, SceneGraph::TextWriter::LEFT_BOTTOM, true ); + // Label the fource + ss << ": " << abs( force ) << " N"; + Vector2 forceDir( norm( force ) * ( 4 * agt->_radius ) + agt->_pos ); + writeText( ss.str(), forceDir, true ); + } + } + + //////////////////////////////////////////////////////////////// + + void AgentContext::drawOrientationFan( const Agent * agt ) { + // Draws orientation as a fan + if ( _showOrient ) { + // Determine the vector rotation for the fan + float angle = agt->getFOV(); + const int SAMPLES = 10; // number of spans in the fan + float dTheta = angle / SAMPLES; + Vector2 dX( cos( dTheta ), sin( dTheta ) ); + Vector2 dY( -dX.y(), dX.x() ); + + // Create the initial point on the fan + Vector2 dir = agt->_orient; + { + float halfAngle = angle * 0.5f; + float c = cos( halfAngle ); + float s = sin( halfAngle ); + float x = dir.x() * c - dir.y() * s; + float y = dir.y() * c + dir.x() * s; + dir.set( x * agt->_neighborDist, y * agt->_neighborDist ); + } + + glEnable( GL_BLEND ); + glColor4f( 0.5f, 0.1f, 0.1f, 0.25f ); + glBegin( GL_TRIANGLE_FAN ); + glVertex3f( agt->_pos.x(), Y, agt->_pos.y() ); + for ( int i = 0; i <= SAMPLES; ++i ) { + // rotate, add, draw + Vector2 pt = agt->_pos + dir; + glVertex3f( pt.x(), Y, pt.y() ); + float x = dir * dX; + float y = dir * dY; + dir.set( x, y ); + + } + + glEnd(); + } + } +} // namespace Zanlungo diff --git a/src/Plugins/AgtZanlungo/ZanlungoAgentContext.h b/src/Plugins/AgtZanlungo/ZanlungoAgentContext.h new file mode 100644 index 00000000..e97a85f4 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoAgentContext.h @@ -0,0 +1,155 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ZanlungoAgentContext.h + * @brief A basic context for interacting with and displaying + * Zanlungo agent parameters + */ + +#ifndef __ZANLUNGO_AGENT_CONTEXT_H__ +#define __ZANLUNGO_AGENT_CONTEXT_H__ + +#include "BaseAgentContext.h" + +using namespace Menge; + +namespace Zanlungo { + // forward declarations + class Agent; + + /*! + * @brief The context for displaying the computational aspects of the + * Zanlungo model (see Agents::Zanlungo::Agent). + */ + class AgentContext : public BaseAgentContext { + public: + /*! + * @brief Constructor. + * + * @param agents An array of pointers to VisAgent instances for Zanlungo + * agents. + * @param agtCount The number of agents contained in the array. + */ + AgentContext( VisAgent ** agents, unsigned int agtCount ); + + /*! + * @brief Returns the name of the context for display. + * + * @returns The name of this context. + */ + virtual std::string contextName() const { return "Zanlungo 2010"; } + + /*! + * @brief Give the context the opportunity to respond to a keyboard + * event. + * + * @param e The SDL event with the keyboard event data. + * @returns A ContextResult instance reporting if the event was handled and + * if redrawing is necessary. + */ + virtual SceneGraph::ContextResult handleKeyboard( SDL_Event & e ); + + protected: + /*! + * @brief Draw context elements into the 3D world. + * + * @param select Defines if the drawing is being done for selection + * purposes (true) or visualization (false). + */ + virtual void draw3DGL( bool select=false ); + + /*! + * @brief Creates a formatted string to be printed in the context + * for a particular agent. + * + * @param agent The agent whose data is to be displayed. + * @returns A formatted string for display in the context's 2D gui. + */ + virtual std::string agentText( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Determines whether the time to interaction is displayed + */ + bool _showTTI; + + /*! + * @brief The id of the time to interaction structure shown. + * If zero, all agents, if positive, a single agent + * if negative, an obstacle + */ + int _ttiObject; + + /*! + * @brief Function for illustrating time to interaction computation. + * + * @param agt The agent whose time to interaction is displayed. + */ + void drawTTI( const Agent * agt ); + + /*! + * @brief Determines if the force vectors are drawn + */ + bool _showForce; + + /*! + * @brief Function for drawing the force vectors acting on agt + * + * @param agt The agent whose forces are displayed. + */ + void drawForce( const Agent * agt ); + + /*! + * @brief Draw the force vector from srcAgent acting on agt + * + * @param agt The agent on which the force is acting + * @param other The agent imparting the force + * @param TTI Time to interaction + */ + void singleAgentForce( const Agent * agt, const Agent * other, float TTI ); + + /*! + * @brief Draws the orientation of the agent + * + * @param agt The agent whose orientation displayed. + */ + void drawOrientationFan( const Agent * agt ); + }; +} // namespace Zanlungo + +#endif // __ZANLUNGO_AGENT_CONTEXT_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/ZanlungoConfig.h b/src/Plugins/AgtZanlungo/ZanlungoConfig.h new file mode 100644 index 00000000..5916f501 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ZanlungoConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __ZANLUNGO_CONFIG_H__ +#define __ZANLUNGO_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( ZANLUNGO_STATICLIB ) + #define ZANLUNGO_API + #else + #if defined( ZANLUNGO_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define ZANLUNGO_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define ZANLUNGO_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( ZANLUNGO_STATICLIB ) + #define ZANLUNGO_API + #else + #if defined( ZANLUNGO_EXPORT ) + #define ZANLUNGO_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define ZANLUNGO_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif //__ZANLUNGO_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/ZanlungoDBEntry.cpp b/src/Plugins/AgtZanlungo/ZanlungoDBEntry.cpp new file mode 100644 index 00000000..aa9aece9 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoDBEntry.cpp @@ -0,0 +1,90 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ZanlungoDBEntry.h" +#include "SimulatorDB.h" +#include "ZanlungoAgentContext.h" +#include "ZanlungoInitializer.h" +#include "SimSystem.h" + +namespace Zanlungo { + ///////////////////////////////////////////////////////////////////////////// + // Implementation of ZanlungoDBEntry + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::briefDescription() const { + return "Simulator based on Zanlungo's 2011 collision prediction pedestrian model"; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::longDescription() const { + return "Simulator based on Zanlungo's 2011 collision prediction pedestrian model\n" + "\tThe model is based on Francesco Zanlungo's 2011 paper.\n" + "\tThe model has been extended in several ways:\n" + "\t 1) Collision prediction now includes precise collision computation,\n" + "\t 2) It includes interaction with obstacles, based on actual collisions."; + } + + ///////////////////////////////////////////////////////////////////////////// + + ::std::string DBEntry::viewerName() const { + return "Zanlungo 2011"; + } + + ///////////////////////////////////////////////////////////////////////////// + + BaseAgentContext * DBEntry::contextFromSystem( SimSystem * system ) { + return new AgentContext( system->getVisAgents(), (unsigned int)system->getAgentCount() ); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::SimulatorInterface * DBEntry::getNewSimulator() { + return new Simulator(); + } + + ///////////////////////////////////////////////////////////////////////////// + + Agents::AgentInitializer * DBEntry::getAgentInitalizer() const { + return new AgentInitializer(); + } + + ///////////////////////////////////////////////////////////////////////////// + +} // namespace Zanlungo diff --git a/src/Plugins/AgtZanlungo/ZanlungoDBEntry.h b/src/Plugins/AgtZanlungo/ZanlungoDBEntry.h new file mode 100644 index 00000000..08d58e26 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoDBEntry.h @@ -0,0 +1,133 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ZanlungoDBEntry.h + * @brief The simulator database entry for the Zanlungo 2011 pedestrian model. + */ + +#ifndef __ZANLUNGO_DB_ENTRY_H__ +#define __ZANLUNGO_DB_ENTRY_H__ + +#include "SimulatorDBEntry.h" +#include "Zanlungo.h" + +using namespace Menge; + +namespace Zanlungo { + /*! + * @brief The simulator database entry for the Zanlungo 2011 simulator. + */ + class DBEntry : public SimulatorDBEntry { + public: + /*! + * @brief Gives a brief description of the simulator. + * + * @returns A brief description of the simulator and pedestrian + * model. + */ + virtual ::std::string briefDescription() const; + + /*! + * @brief Gives a long description of the simulator. + * + * @returns A long description of the simulator and pedestrian + * model. + */ + virtual ::std::string longDescription() const; + + /*! + * @brief Gives a label to apply to the interactive viewer. + * + * @returns The name for display on the interactive viewer. + */ + virtual ::std::string viewerName() const; + + /*! + * @brief Gives a unique name to be used as a command-line parameter. + * + * This name MUST satisfy two constraints: + * - It must contain no spaces. + * - It must be unique from that used by all other simulators. + * + * @returns A single string (with no spaces) that can be used as + * a command line parameter to uniquely identify this model. + */ + virtual ::std::string commandLineName() const { return "zanlungo"; } + + /*! + * @brief Returns a pointer to this model's Simulator instance. + * + * This must be overridden by a derived class + * + * @returns A newly instantiated simulator instance of a type appropriate + * for this database entry. + */ + virtual Agents::SimulatorInterface * getNewSimulator(); + + /*! + * @brief Provides an AgentInitializer appropriate to this simulator class. + * + * @returns A pointer to an agent initializer. The caller is responsible for + * freeing up the memory. + */ + virtual Agents::AgentInitializer * getAgentInitalizer() const; + + protected: + /*! + * @brief Returns a pointer to an agent context appropriate to + * the corresponding simulator. + * + * If the provided system is not, in fact, a pointer to a SimSystem for the + * appropriate simulator type, this function will report failure. Furthermore, + * the default implementation is to return a BaseAgentContext. If the + * simulator comes with a novel context, this function should be overridden + * in the derived SimulatorDBEntry. + * + * @param system The system which tracks the agents. This should be + * the same system which was returned by a call to + * SimulatorDBEntryBase::getSimulatorSystem. + * @returns A pointer to the appropriate agent context. If the system is of + * the wrong type (or if there is any other problem), NULL is returned. + */ + virtual BaseAgentContext * contextFromSystem( SimSystem * system ); + }; +} // namespace Zanlungo + +#endif // __ZANLUNGO_DB_ENTRY_H__ + diff --git a/src/Plugins/AgtZanlungo/ZanlungoInitializer.cpp b/src/Plugins/AgtZanlungo/ZanlungoInitializer.cpp new file mode 100644 index 00000000..df6f3186 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoInitializer.cpp @@ -0,0 +1,128 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ZanlungoInitializer.h" +#include "ZanlungoAgent.h" +#include "Math/RandGenerator.h" + +namespace Zanlungo { + //////////////////////////////////////////////////////////////// + // Implementation of Zanlungo::AgentInitializer + //////////////////////////////////////////////////////////////// + + // Default values + const float MASS = 80.f; ///< The default agent mass. + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer() : Agents::AgentInitializer() { + _mass = new ConstFloatGenerator( MASS ); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::AgentInitializer( const AgentInitializer & init ) : Agents::AgentInitializer(init) { + _mass = init._mass->copy(); + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::~AgentInitializer() { + delete _mass; + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::setProperties( Agents::BaseAgent * agent ) { + Agent * a = dynamic_cast< Agent * >( agent ); + if ( a == 0x0 ) return false; + a->_mass = _mass->getValue(); + return Agents::AgentInitializer::setProperties( agent ); + } + + //////////////////////////////////////////////////////////////// + + bool AgentInitializer::isRelevant( const ::std::string & tagName ) { + return ( tagName == "Zanlungo" ) || Agents::AgentInitializer::isRelevant( tagName ); + } + + //////////////////////////////////////////////////////////////// + + Agents::AgentInitializer::ParseResult AgentInitializer::setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ) { + ParseResult result = IGNORED; + if ( paramName == "mass" ) { + result = constFloatGenerator( _mass, value ); + } + + if ( result == FAILURE ) { + logger << Logger::WARN_MSG << "Attribute \"" << paramName << "\" had an incorrectly formed value: \"" << value << "\". Using default value."; + result = ACCEPTED; + } else if ( result == IGNORED ){ + return Agents::AgentInitializer::setFromXMLAttribute( paramName, value ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + AgentInitializer::ParseResult AgentInitializer::processProperty( ::std::string propName, TiXmlElement * node ) { + ParseResult result = IGNORED; + if ( propName == "mass" ) { + result = getFloatGenerator( _mass, node ); + } + + if ( result == FAILURE ) { + logger << Logger::ERR_MSG << "Error extracting value distribution from Property " << propName << "."; + return result; + } else if ( result == IGNORED ) { + return Agents::AgentInitializer::processProperty( propName, node ); + } + return result; + } + + //////////////////////////////////////////////////////////////// + + void AgentInitializer::setDefaults() { + if ( _mass ) delete _mass; + _mass = new ConstFloatGenerator( MASS ); + Agents::AgentInitializer::setDefaults(); + } + + //////////////////////////////////////////////////////////////// + +} // namespace Zanlungo diff --git a/src/Plugins/AgtZanlungo/ZanlungoInitializer.h b/src/Plugins/AgtZanlungo/ZanlungoInitializer.h new file mode 100644 index 00000000..56b7e9db --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoInitializer.h @@ -0,0 +1,169 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ZanlungoInitializer.h + * @brief The AgentInitializer for the Zanlungo simulator. + */ +#ifndef __ZANLUNGO_INITIALIZER_H__ +#define __ZANLUNGO_INITIALIZER_H__ + +#include "AgentInitializer.h" + +using namespace Menge; + +namespace Zanlungo { + /*! + * @brief Class which determines the agent properties for each new Zanlungo agent. + */ + class AgentInitializer : public Agents::AgentInitializer { + public: + /*! + * @brief Constructor. + * + * The values for each agent take a hard-coded default values. + */ + AgentInitializer(); + + /*! + * @brief Copy Constructor. + * + * @param init The initializer to copy values from + */ + AgentInitializer( const AgentInitializer & init ); + + /*! + * @brief Destructor. + */ + virtual ~AgentInitializer(); + + /*! + * @brief Sets the properties of the given agent based on the initializer's + * values. + * + * This needs to be overridden by sub-classes. The first thing the sub-class + * should do is dynamic_cast the argument to its expected type to make sure it + * is the proper agent type. If not, this should be considered failure. + * Then it should set its unique properties an+d then call the super class's + * setProperties function. + * + * @param agent The agent whose properties are to be set. + * @returns True if the properties were set successfully, false otherwise. + */ + virtual bool setProperties( Agents::BaseAgent * agent ); + + /*! + * @brief Sets all generators to default values. + * + * Resets all number generators to default const values. This assumes that all + * required number generators already exist and will delete them appropriately. + * *Do not* call this in the constructor. + */ + virtual void setDefaults(); + + /*! + * @brief Creates a copy of this AgentInitializer instance. + * + * @returns A pointer to a new AgentInitializer with all of the same values + * as this. The caller is responsible for freeing up the + * new instance. + */ + virtual AgentInitializer * copy() const { return new AgentInitializer( *this ); } + + protected: + + /*! + * @brief Reports if this AgentInitializer cares about the given AgentSet + * property XML tag. + * + * This is the mechanism by which new sub-classes can extend the parameter + * space. Each pedestrian model which introduces new per-agent properties that + * must override this function. However, the overriden function must, in turn, + * call the parent class if it doesn't consider the tag relevant, giving the + * parent class a chance to determine if the tag is relevant. This is the + * mechanism by which derived classes will also benefit from the `<Zanlungo>` + * parameter set. + * + * @param tagName The tag to test for relevancy. + * @returns True if the tag is relevant, false otherwise. + */ + virtual bool isRelevant( const ::std::string & tagName ); + + /*! + * @brief Defines a constant value for an agent property as specified + * by the attribute of an agent property tag. + * + * Derived classes should override this function, but possibly call the parent + * class's implementation. First, it should test to see if the paramName is + * expected by the derived class. If so, the derived class can determine fail + * or accept. If it is not expected, it should call the parent class's implementation + * and returns its value. + * + * @param paramName A string containing the parameter name. + * @param value A string containing the value for the parameter. + * @returns The result of the parse: failure, ignored, or accepted. + */ + virtual Agents::AgentInitializer::ParseResult setFromXMLAttribute( const ::std::string & paramName, const ::std::string & value ); + + /*! + * @brief Process the given <Property .../> tag. + * + * As a pre-condition to this function, the XML node contains a <Property.../> + * tag and has been confirmed to have, at least, a name attribute. Nothing + * else about the tag has been validated. + * + * If the property name is unexpected, it will be ignored. If it is expected, + * this function will attempt to interpret the XML tag as a number distribution + * for a valid agent attribute. If it can do so, it is successful, if it can't, + * it fails. + * + * @param propName The extractd "name" property from the Property tag. + * @param node The XML node for the Property tag. + * @returns True if parsing was "successful", false otherwise. + */ + virtual ParseResult processProperty( ::std::string propName, TiXmlElement * node ); + + /*! + * @brief The mass of the agent. + */ + FloatGenerator * _mass; + }; +} // namespace Zanlungo + + +#endif // __ZANLUNGO_INITIALIZER_H__ \ No newline at end of file diff --git a/src/Plugins/AgtZanlungo/ZanlungoSimulator.cpp b/src/Plugins/AgtZanlungo/ZanlungoSimulator.cpp new file mode 100644 index 00000000..4d87bf88 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoSimulator.cpp @@ -0,0 +1,75 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ZanlungoSimulator.h" +#include "Utils.h" + +namespace Zanlungo { + //////////////////////////////////////////////////////////////// + // Implementation of Zanlungo::Simulator + //////////////////////////////////////////////////////////////// + + // Where do these values come from? + float Simulator::AGENT_SCALE = 2000.f; + float Simulator::OBST_SCALE = 2000.f; + float Simulator::REACTION_TIME = 0.5f; + float Simulator::FORCE_DISTANCE = 0.08f; + + //////////////////////////////////////////////////////////////// + + bool Simulator::setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ) { + try { + if ( paramName == "agent_scale" ) { + AGENT_SCALE = toFloat( value ); + } else if ( paramName == "obstacle_scale" ) { + OBST_SCALE = toFloat( value ); + } else if ( paramName == "reaction_time" ) { + REACTION_TIME = toFloat( value ); + } else if ( paramName == "force_distance" ) { + FORCE_DISTANCE = toFloat( value ); + } else if ( ! Agents::SimulatorBase< Agent >::setExpParam( paramName, value ) ) { + // Simulator base didn't recognize the parameter either + return false; + } + } catch ( UtilException ) { + throw Agents::XMLParamException( std::string( "Zanlungo parameter \"") + paramName + std::string("\" value couldn't be converted to the correct type. Found the value: " ) + value ); + } + + return true; + } +} //namespace Zanlungo diff --git a/src/Plugins/AgtZanlungo/ZanlungoSimulator.h b/src/Plugins/AgtZanlungo/ZanlungoSimulator.h new file mode 100644 index 00000000..8d39fd35 --- /dev/null +++ b/src/Plugins/AgtZanlungo/ZanlungoSimulator.h @@ -0,0 +1,127 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __ZANLUNGO_SIMULATOR_H__ +#define __ZANLUNGO_SIMULATOR_H__ + +/*! + * @file ZanlungoSimulator.h + * @brief Contains the Zanlungo::Simulator class + * + * Implements Zanlungo's 2011 pedestrian model + * "Social Force Model with Explicit Collision Prediction" + */ + +#include "mengeCommon.h" +#include "SimulatorBase.h" +#include "ZanlungoAgent.h" + +using namespace Menge; + +/*! + * @namespace Zanlungo + * @brief Contains the specification of the pedestrian model + * based on the Zanlungo et al., 2011 paper. + */ +namespace Zanlungo { + /*! + * @brief Defines the simulator operating on a Zanlungo::Agent. + */ + class Simulator : public Agents::SimulatorBase< Agent > { + public: + /*! + * @brief Constructor. + */ + Simulator(): Agents::SimulatorBase< Agent >() {} + + /*! + * @brief Reports if there are non-common Experiment parameters that + * this simulator requires in the XML file. + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool hasExpTarget() { return true; } + + /*! + * @brief Reports if the given Experiment attribute tag name belongs to this + * simulator. + * @param tagName the name of the considered tag + * @returns By default, the simulator base ONLY uses common parameters. + * Always returns false. + */ + virtual bool isExpTarget( const std::string & tagName ) { return tagName == "Zanlungo"; } + + /*! + * @brief Given an Experiment parameter name and value, sets the appropriate + * simulator parameter. + * @param paramName A string containing the parameter name for the experiment. + * @param value A string containing the value for the parameter. + * @returns whether or not parameters were successfully set + */ + virtual bool setExpParam( const std::string & paramName, const std::string & value ) throw( Agents::XMLParamException ); + + protected: + friend class Agent; + /*! + * @brief The magnitude of the inter-agent repulsion forces + * In the paper, this is the parameter A in the agent repulsion force + */ + static float AGENT_SCALE; + + /*! + * @brief The magnitude of the agent-obstacle repulsion forces + * This variable is not in the paper (dealing with obstacles is not + * discussed.) However, this is the equivalent of AGENT_SCALE + * but for obstacles. + */ + static float OBST_SCALE; + + /*! + * @brief The reaction time used to define the driving force + */ + static float REACTION_TIME; + + /*! + * @brief The the fall-off distance of repulsive forces + * In the paper, this is the parameter B in the agent repulsion force. + */ + static float FORCE_DISTANCE; + }; +} // namespace Zanlungo + +#endif // __ZANLUNGO_SIMULATOR_H__ \ No newline at end of file diff --git a/src/Plugins/Formations/Formations.cpp b/src/Plugins/Formations/Formations.cpp new file mode 100644 index 00000000..086f31c2 --- /dev/null +++ b/src/Plugins/Formations/Formations.cpp @@ -0,0 +1,78 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Formations.cpp + * @brief Plugin for formations + */ + +#include "FormationsConfig.h" +#include "FormationsModifier.h" +#include "FreeFormation.h" +#include "FormationsTask.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" FORMATIONS_API const char * getName() { + return "formations"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" FORMATIONS_API const char * getDescription() { + return "Utilities for adding formations to ped sims" \ + "including the following:\n"\ + "\tModifier \"formation\" - forces agents to move in formation. " ; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" FORMATIONS_API void registerPlugin( PluginEngine * engine ) { + engine->registerVelModFactory( new Formations::FormationModifierFactory() ); +} + diff --git a/src/Plugins/Formations/FormationsConfig.h b/src/Plugins/Formations/FormationsConfig.h new file mode 100644 index 00000000..8a0437f3 --- /dev/null +++ b/src/Plugins/Formations/FormationsConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FORMATIONSConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __FORMATIONS_CONFIG_H__ +#define __FORMATIONS_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( FORMATIONS_STATICLIB ) + #define FORMATIONS_API + #else + #if defined( FORMATIONS_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define FORMATIONS_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define FORMATIONS_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( FORMATIONS_STATICLIB ) + #define FORMATIONS_API + #else + #if defined( FORMATIONS_EXPORT ) + #define FORMATIONS_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define FORMATIONS_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __FORMATIONS_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/Formations/FormationsModifier.cpp b/src/Plugins/Formations/FormationsModifier.cpp new file mode 100644 index 00000000..6178406b --- /dev/null +++ b/src/Plugins/Formations/FormationsModifier.cpp @@ -0,0 +1,159 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __FORMATIONS_MODIFIER_CPP__ +#define __FORMATIONS_MODIFIER_CPP__ + +#include "FormationsModifier.h" +#include "FormationsTask.h" + +namespace Formations { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FormationModifier + ///////////////////////////////////////////////////////////////////// + + FormationModifier::FormationModifier() { + } + + ///////////////////////////////////////////////////////////////////// + + FormationModifier::~FormationModifier(){ + }; + + ///////////////////////////////////////////////////////////////////// + + FormationModifier::FormationModifier( FormationPtr form ){ + _formation = form; + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::VelModifier* FormationModifier::copy() const{ + return new FormationModifier( _formation ); + }; + + ///////////////////////////////////////////////////////////////////// + + void FormationModifier::adaptPrefVelocity( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ){ + //adapt the agent's velocity according to the formation + Vector2 target = Vector2( 0.f, 0.f ); + _lock.lockRead(); + bool modify = _formation->getGoalForAgent( agent, pVel, target ); + _lock.releaseRead(); + if ( modify ) { + pVel.setTarget(target); + pVel.setSpeed(agent->_prefSpeed); + Vector2 dir = target - agent->_pos; + // TODO: The units don't match + // ||dir|| is meters, speed is m/s -- how does this work? + // Also, I'm normalizing dir possibly THREE times - that's a lot of + // square roots. + if ( abs( dir ) < pVel.getSpeed() ){ + pVel.setSpeed( abs( dir ) ); + } + dir.normalize(); + pVel.setSingle( dir ); + } + } + + ///////////////////////////////////////////////////////////////////// + + void FormationModifier::setFormation(FormationPtr form){ + _formation = form; + }; + + ///////////////////////////////////////////////////////////////////// + + BFSM::Task * FormationModifier::getTask(){ + return new FormationsTask( _formation ); + }; + + ///////////////////////////////////////////////////////////////////// + + void FormationModifier::registerAgent(const Agents::BaseAgent * agent){ + _lock.lockWrite(); + _formation->addAgent(agent); + _lock.releaseWrite(); + }; + + ///////////////////////////////////////////////////////////////////// + + void FormationModifier::unregisterAgent(const Agents::BaseAgent * agent){ + _lock.lockWrite(); + _formation->removeAgent(agent); + _lock.releaseWrite(); + }; + + ///////////////////////////////////////////////////////////////////// + // Implementation of FormationModFactory + ///////////////////////////////////////////////////////////////////// + + FormationModifierFactory::FormationModifierFactory():BFSM::VelModFactory() { + //no properties yet + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool FormationModifierFactory::setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const { + FormationModifier * formationMod = dynamic_cast<FormationModifier *>(modifier); + assert( formationMod != 0x0 && "Trying to set property modifier properties on an incompatible object" ); + + if ( ! BFSM::VelModFactory::setFromXML( modifier, node, behaveFldr ) ) return false; + + // get the absolute path to the file name + + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + FormationPtr formPtr; + try { + formationMod->setFormation(loadFormation( fName )); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the formation referenced on line " << node->Row() << "."; + return false; + } + + return true; + } + + ///////////////////////////////////////////////////////////////////// +}; +#endif diff --git a/src/Plugins/Formations/FormationsModifier.h b/src/Plugins/Formations/FormationsModifier.h new file mode 100644 index 00000000..1517d91f --- /dev/null +++ b/src/Plugins/Formations/FormationsModifier.h @@ -0,0 +1,230 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FormationsModifier.h + * @brief definition of a VelocityModifier to enforce formation behavior + */ +#ifndef __FORMATIONS_MODIFIER_H__ +#define __FORMATIONS_MODIFIER_H__ + +#include "FormationsConfig.h" +#include "FreeFormation.h" +#include "VelocityModifiers/VelModifier.h" +#include "VelocityModifiers/VelModifierFactory.h" +#include "FSMEnumeration.h" +#include "ReadersWriterLock.h" + +using namespace Menge; + +#if defined(_MSC_VER) + // Visual Studio spews warnings about some members. + // It wants them to be exposed in the dll IN CASE a client uses it. + //TODO: remove this warning supression, correct the problem + #pragma warning(disable:4251) +#endif + +//forward declaration +class TiXmlElement; + +namespace Formations { + + // forward declaration + class FormationModifierFactory; + + /*! + * @brief A velocity modifier which adapts agent preferred velocities + * so that they move in formations. + */ + class FORMATIONS_API FormationModifier : public BFSM::VelModifier { + public: + /*! + * @brief Constructor + */ + FormationModifier(); + + /*! + * @brief Constructor for given Formation + * + * @param form A managed pointer to formation data + */ + FormationModifier( FormationPtr form ); + + protected: + /*! + * @brief Destructor. + */ + virtual ~FormationModifier(); + + public: + + /*! + * @brief Creates a copy of this velocity modifier. + */ + BFSM::VelModifier* copy() const; + + /*! + * @brief Adapt the input preferred velocity according to the formation. + * + * @param agent The agent whose preferred velocity is provided. + * @param pVel The preferred velocity to modify -- modified in place. + */ + void adaptPrefVelocity( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ); + + /*! + * @brief Provides the task the formation modifier uses to update formations. + * + * @returns A pointer to the supporting task. The caller is responsible to delete it. + */ + virtual BFSM::Task * getTask(); + + /*! + * @brief Set the formation data. + * + * @param form A managed resource pointer to the underlying formation data. + */ + void setFormation( FormationPtr form ); + + /*! + * @brief Register an agent to be affected by this velocity modifier. + */ + void registerAgent(const Agents::BaseAgent * agent); + + /*! + * @brief Unregister an agent from being affected by this velocity modifier. + */ + void unregisterAgent(const Agents::BaseAgent * agent); + + /*! + * @brief Provides a display context for interacting with this velocity modifier + * + * It is the responsibility of the caller to delete the provided context. + * + * @returns A pointer to a context for this velocity modifier + */ + //virtual VelModContext * getContext(); + + friend class FormationModifierFactory; + + protected: + + /*! + * @brief The underlying formation data. + */ + FormationPtr _formation; + + /*! + * @brief Concurrency lock for _formation. + */ + ReadersWriterLock _lock; + + }; + + /////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory class for the FormationModifier + */ + class FORMATIONS_API FormationModifierFactory : public BFSM::VelModFactory { + public: + /*! + * @brief Constructor. + */ + FormationModifierFactory(); + + /*! + * @brief The name of the modifier + * + * The modifier's name must be unique among all registered modifier. + * Each modifier factory must override this function. + * + * @returns A string containing the unique modifier name. + */ + virtual const char * name() const { return "formation"; } + + /*! + * @brief A description of the modifier + * + * Each modifier factory must override this function. + * + * @returns A string containing the modifier description. + */ + virtual const char * description() const { + return "Forces agents in this state or machine to move in formation"; + }; + + protected: + /*! + * @brief Create an instance of this class's modifier. + * + * All modifierFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding modifier type. The various field values + * of the instance will be set in a subsequent call to modifierFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated modifier class. + */ + BFSM::VelModifier * instance() const { return new FormationModifier(); } + + /*! + * @brief Given a pointer to an modifier instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this modifier's type. + * (i.e. modifierFactory::thisFactory has already been called and returned true.) + * If sub-classes of modifierFactory introduce *new* modifier parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param modifier A pointer to the modifier whose attributes are to be set. + * @param node The XML node containing the modifier attributes. + * @param behaveFldr The path to the behavior file. If the modifier references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; +}; +#endif diff --git a/src/Plugins/Formations/FormationsTask.cpp b/src/Plugins/Formations/FormationsTask.cpp new file mode 100644 index 00000000..b40833b6 --- /dev/null +++ b/src/Plugins/Formations/FormationsTask.cpp @@ -0,0 +1,82 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "FormationsTask.h" +#include "FreeFormation.h" +#include "FSM.h" + +namespace Formations { + + ///////////////////////////////////////////////////////////////////// + // Implementation of FormationsTask + ///////////////////////////////////////////////////////////////////// + + FormationsTask::FormationsTask( Formations::FormationPtr & f): BFSM::Task(), _formation(f) { + } + + ///////////////////////////////////////////////////////////////////// + + void FormationsTask::doWork( const BFSM::FSM * fsm ) throw( BFSM::TaskException ) { + _formation->mapAgentsToFormation(fsm); + } + ///////////////////////////////////////////////////////////////////// + + std::string FormationsTask::toString() const { + return "Formation Task"; + } + + ///////////////////////////////////////////////////////////////////// + + bool FormationsTask::isEquivalent( const BFSM::Task * task ) const { + const FormationsTask * other = dynamic_cast< const FormationsTask * >( task ); + if ( other == 0x0 ) { + return false; + } else { + other->getFormation(); + + if ( other->getFormation() == _formation){ + return true; + } else { + return false; + } + } + } + + ///////////////////////////////////////////////////////////////////// + +} // namespace BFSM diff --git a/src/Plugins/Formations/FormationsTask.h b/src/Plugins/Formations/FormationsTask.h new file mode 100644 index 00000000..a5da93ce --- /dev/null +++ b/src/Plugins/Formations/FormationsTask.h @@ -0,0 +1,119 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FormationsTask.h + * @brief Task used to maintain a single formation. + */ + +#ifndef __FORMATIONS_TASK_H__ +#define __FORMATIONS_TASK_H__ + +#include "Tasks/Task.h" +#include "fsmCommon.h" +#include <string> +#include "Tasks/TaskFactory.h" +#include "tinyxml.h" +#include "FreeFormation.h" +#include "FormationsModifier.h" + +using namespace Menge; + +namespace Formations { + /*! + * @brief Task responsible for updating agent data for maintaining a formation. + */ + class FormationsTask : public BFSM::Task { + public: + /*! + * @brief Constructor + * + * @param form The formation to be maintained in the task. + * + */ + FormationsTask( Formations::FormationPtr & form ); + + /*! + * @brief The work performed by the task. + * + * @param fsm The finite state machine for the task to operate on. + * @throws A TaskException if there was some non-fatal error + * in execution. It should be logged. + * @throws A TaskFatalException if there is a fatal error that + * should arrest execution of the simulation. + */ + virtual void doWork( const BFSM::FSM * fsm ) throw( BFSM::TaskException ); + + /*! + * @brief String representation of the task + * + * @returns A string containing task information. + */ + virtual std::string toString() const; + + /*! + * @brief Reports if this task is "equivalent" to the given task. + * This makes it possible for a task to be redundantly added + * to the fsm without fear of duplication as the equivalent + * duplicates will be culled. + * + * @param task The task to test against this one. + * @returns A boolean reporting if the two tasks are equivalent (true) + * or unique (false). + */ + virtual bool isEquivalent( const BFSM::Task * task ) const; + + /*! + * @brief Get the formation represented in this task + * + * @returns The FormationPtr object containing the formation resource + */ + const Formations::FormationPtr getFormation() const { return _formation;} + + protected: + /*! + * @brief The underlying formation data. + */ + Formations::FormationPtr _formation; //the formation + + }; + + + +} +#endif // __DENSITY_GRID_TASK_H__ diff --git a/src/Plugins/Formations/FreeFormation.cpp b/src/Plugins/Formations/FreeFormation.cpp new file mode 100644 index 00000000..76798ebf --- /dev/null +++ b/src/Plugins/Formations/FreeFormation.cpp @@ -0,0 +1,431 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/* +* Freestyle formation +* http://graphics.cs.uh.edu/wp-content/papers/2013/2011_CGA-crowd-formation-generation-preprint.pdf +*/ + +#include "FreeFormation.h" +#include "SimulatorInterface.h" +#include "VelocityModifiers/VelModifier.h" +#include "Core.h" + +namespace Formations { + ///////////////////////////////////////////////////////////////////// + // Implementation of FreeFormation + ///////////////////////////////////////////////////////////////////// + + const std::string FreeFormation::LABEL("formation"); + + ///////////////////////////////////////////////////////////////////// + + FreeFormation::FreeFormation(const std::string & name): Resource(name){ + _speed = 0.0f; + _direction = Vector2(1,0); + _pos = Vector2(0,0); + _agentRadius = 0; + }; + + ///////////////////////////////////////////////////////////////////// + + FreeFormation::~FreeFormation(){ + //we're certainly not allowed to delete the agents! + //but we should clear the vectors we control. + + std::vector<FormationPoint *>::iterator fpIter = _formationPoints.begin(); + for ( ; fpIter != _formationPoints.end(); ++fpIter ) { + delete *fpIter; + } + + //in all actuality, we don't have to do anything the data is constructed in such a way to implicitly handle this + + // The problem with this is that this is TWO data structures that have been + // merged. The *static* underlying formation definition, and the *dynamic* + // data mapping agents to that formation. + }; + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::addAgent( const Agents::BaseAgent *agt ) { + if ( _agents.find( agt->_id ) == _agents.end() ){ + _agents[ agt->_id ] = agt; + _agentWeights[ agt->_id ] = 1.0f; // default weight - this never changes + } + }; + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::removeAgent( const Agents::BaseAgent *agt ) { + std::map<size_t, const Agents::BaseAgent *>::iterator itr = _agents.find( agt->_id ); + if ( itr != _agents.end()){ + _agents.erase( itr ); + } + }; + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::addFormationPoint(Vector2 point, bool borderPoint, float weight ) { + //now add the point + FormationPoint *pt = new FormationPoint(); + + pt->_id = _formationPoints.size(); + pt->_pos = point; + pt->_dist = abs( point ); + pt->_dir = pt->_dist > 1e-5 ? -( point / pt->_dist ) : Vector2(0.f, 0.f); + pt->_border = borderPoint; + pt->_weight = weight; + + _formationPoints.push_back(pt); + if (pt->_border){ + //add this to the border list. DATA REDUNDANCY but we consider it a cache for mapping + _borderPoints.push_back(pt); + } + } + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::addAgentPoint(const Agents::BaseAgent *agt) { + //make a sentinel point + FormationPoint *agtPoint = new FormationPoint(); + + agtPoint->_id = agt->_id; + agtPoint->_pos = agt->_pos; + agtPoint->_dir = _pos - agt->_pos; + agtPoint->_dist = abs( agtPoint->_dir ); + agtPoint->_border = false; + agtPoint->_weight = 0.0f; + + //normalize direction + if ( agtPoint->_dist > 1e-5f ) { + agtPoint->_dir /= agtPoint->_dist; + } + + //we'll convert to formation coordinates later + if (agtPoint->_dist > _agentRadius){ + _agentRadius = agtPoint->_dist; + } + + //now store it + _agentPoints[agt->_id] = agtPoint; + } + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::normalizeFormation() { + std::vector<FormationPoint *>::iterator fpIter = _formationPoints.begin(); + + // Compute weighted center of the reference formation + Vector2 weightedCenter(0.f, 0.f); + float totalWeight = 0.f; + for (; fpIter != _formationPoints.end(); ++fpIter){ + weightedCenter += (*fpIter)->_pos * (*fpIter)->_weight; + totalWeight += (*fpIter)->_weight; + } + //average the weighted center + weightedCenter /= totalWeight; + + // Translate to canonical formation space and determine formation size + // offset by weighted center and compute encompassing circle. + float formationRadius = 0.f; + for ( ; fpIter != _formationPoints.end(); ++fpIter ) { + (*fpIter)->_pos -= weightedCenter; + (*fpIter)->_dist = abs( (*fpIter)->_pos ); + if ( (*fpIter)->_dist > formationRadius ){ + formationRadius = (*fpIter)->_dist; + } + } + + float invDist = 1.f / formationRadius; + // Scale all distances + for (; fpIter != _formationPoints.end(); ++fpIter){ + (*fpIter)->_dist *= invDist; + (*fpIter)->_pos *= invDist; + } + } + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::mapAgentsToFormation(const BFSM::FSM * fsm) { + //we need intermediate vars + std::vector<FormationPoint *>::const_iterator formationItr; + const Agents::BaseAgent *agt; + size_t exceptionCount = 0; // delete me + size_t agtCount = 0; + std::map<size_t,const Agents::BaseAgent *>::iterator itr; //agents + std::map<size_t, FormationPoint *>::iterator mapIter; //agent points + float totalWeight = 0.0f; + //reset vars + _pos.set( 0.f, 0.f ); + _direction.set( 0.f, 0.f ); + _speed = 0.0f; + _agentRadius = 0.0f; + + //clear the relationships + // TODO: Anything that maps agents -> value should NOT clear at each time + // step. The structure of these objects should only change when the + // agents in the formation changes. Not just to update values. + _agent_formationPoint.clear(); + _formationPoint_agent.clear(); + mapIter = _agentPoints.begin(); + for ( ; mapIter != _agentPoints.end(); ++mapIter ){ + delete mapIter->second; + } + _agentPoints.clear(); + + // Compute formation world position, direction, and speed + float totalSpeed = 0.f; + for ( itr = _agents.begin(); itr != _agents.end(); ++itr ) { + agt = itr->second; + + _pos += agt->_pos * _agentWeights[agt->_id]; + totalWeight += _agentWeights[agt->_id]; + //see if we have a cache + if (_agentPrefDirs.find(agt->_id) == _agentPrefDirs.end()){ + _direction += agt->_velPref.getPreferredVel(); + } else { + _direction += _agentPrefVels[agt->_id]; + } + totalSpeed += agt->_velPref.getSpeed(); + ++agtCount; + } + + //now that we can localize and normalize the formation, let's do so. + _pos /= totalWeight; + float mag = abs( _direction ); + _speed = totalSpeed > 0.f ? mag / totalSpeed : mag ; + if ( mag > 1e-5 ) { + _direction /= mag; + } + + // Define "sentinel" points for the agents -- currently unnormalized. + for ( itr = _agents.begin(); itr != _agents.end(); ++itr ) { + agt = itr->second; + //make a sentinel point + addAgentPoint(agt); + } + + // First select agents for the border points + formationItr = _borderPoints.begin(); + for ( ; formationItr != _borderPoints.end(); ++formationItr ){ + mapPointToAgent( *formationItr ); + } + + // Finally, map formation points to the remaining agents + itr = _agents.begin(); + for (;itr != _agents.end();++itr){ + agt = itr->second; + if ( _agent_formationPoint.find( agt->_id) == _agent_formationPoint.end() ){ + mapAgentToPoint(agt); + } + } + }; + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::mapAgentToPoint( const Agents::BaseAgent * agt ){ + // This uses a brute-force approach of teseting every formation + // point for the agent. No spatial queries. + + // The corresponding sentinel point for this agent + FormationPoint * agtPoint = _agentPoints[agt->_id]; + + std::vector<FormationPoint *>::iterator fpIter = _formationPoints.begin(); + size_t minPt = -1; // min pt for mapping + float distance, minDistance; + distance = minDistance = 1000000.0f; + + for ( ; fpIter != _formationPoints.end(); ++fpIter ){ + FormationPoint * formPt = *fpIter; + if ( _formationPoint_agent.find( formPt->_id ) == _formationPoint_agent.end() ) { + // so the keypoint is not mapped. get the distance + distance = formationDistance( agtPoint, formPt ); + if (distance < minDistance) { + minDistance = distance; + minPt = formPt->_id; + } + } + } + + if (minPt == -1) { + // TODO: Although this claims to be "fatal", it doesn't cause the + // program to crash. Make the exception appropriate. + throw BFSM::VelModFatalException( "Not enough points in formation." ); + } else { + _formationPoint_agent[ minPt ] = agtPoint->_id; + _agent_formationPoint[ agtPoint->_id ] = minPt; + _agentWeights[ agt->_id ] = _formationPoints[ minPt ]->_weight; + } + }; + + ///////////////////////////////////////////////////////////////////// + + void FreeFormation::mapPointToAgent( FormationPoint * pt ){ + // This does a brute-force, linear search through the agents to find + // the "nearest" candidate. + + //iterate over the agents and find the best agent for this point + std::map< size_t, const Agents::BaseAgent * >::const_iterator itr; + FormationPoint * agtPoint; + float distance, minDistance; + distance = minDistance = 1000000.0; + size_t minAgtID = -1; + + for ( itr = _agents.begin(); itr != _agents.end(); ++itr ){ + const Agents::BaseAgent * agt = itr->second; + //make sure the agent isn't already mapped to a border + if (_agent_formationPoint.find( agt->_id ) == _agent_formationPoint.end() ) { + //check distance + agtPoint = _agentPoints[ agt->_id ]; + + //check distance + distance = formationDistance( pt, agtPoint ); + if (distance < minDistance) { + minDistance = distance; + minAgtID = itr->second->_id; + } + } + } + + // ignore if minAgtID == -1: This means there were insufficient agents + // for the formation. This is not a problem. + if ( minAgtID > -1 ) { + _formationPoint_agent[ pt->_id ] = minAgtID; + _agent_formationPoint[ minAgtID ] = pt->_id; + _agentWeights[ minAgtID ] = _formationPoints[ pt->_id ]->_weight; + } + }; + + ///////////////////////////////////////////////////////////////////// + + bool FreeFormation::getGoalForAgent( const Agents::BaseAgent * agt, Agents::PrefVelocity &pVel, Vector2 &target) { + // The goal point is the agent's corresponding sential point (with the point moving the formations + // direction and speed.) + + //cache input pref dir + _agentPrefDirs[ agt->_id ] = pVel.getPreferred(); + _agentPrefVels[ agt->_id ] = pVel.getPreferredVel(); + + // assuming this is only called on agents in the formation + assert(_agents.find(agt->_id) != _agents.end() && "Trying to get a formation goal for an agent that is not in the formation" ); + + //the first frame an agent enters a formation does not guaruntee it has been mapped. + if (_agent_formationPoint.find(agt->_id) != _agent_formationPoint.end()) { + target = _formationPoints[ _agent_formationPoint[ agt->_id ] ]->_pos + _pos; + target = target + _direction * _speed; + return true; + } + + return false; + }; + + ///////////////////////////////////////////////////////////////////// + + float FreeFormation::formationDistance(FormationPoint *pt1, FormationPoint *pt2){ + Vector2 relDir( pt1->_dir - pt2->_dir ); + return sqrtf( absSq( relDir ) + sqr( pt1->_dist - pt2->_dist ) ); + } + + ///////////////////////////////////////////////////////////////////// + + Resource * FreeFormation::load( const std::string & fileName ) { + // TODO: Change this to support comments. + std::ifstream f; + f.open( fileName.c_str(), std::ios::in ); + + if ( !f.is_open() ) { + logger << Logger::ERR_MSG << "Error opening formation file: " << fileName << "."; + return 0x0; + } + + // load vertices + unsigned int borderCount; + if ( ! ( f >> borderCount ) ) { + logger << Logger::ERR_MSG << "Error in parsing formation: file didn't start with border vertex count."; + return 0x0; + } + + FreeFormation * form = new FreeFormation( fileName ); + + float x, y, weight; + for ( unsigned int v = 0; v < borderCount; ++v ) { + if ( ! ( f >> x >> y >> weight ) ) { + logger << Logger::ERR_MSG << "Error in parsing formation: format error for vertex " << ( v + 1 ) << "."; + form->destroy(); + return 0x0; + } + form->addFormationPoint( Vector2( x, y ), true, weight ); + } + + //while we have points left, they are internal points + if ( ( f >> x >> y >> weight ) ) { + while ( !f.eof() ) { + form->addFormationPoint( Vector2( x, y ), false, weight ); + if ( f >> x ){ + if (!(f >> y >> weight)){ + logger << Logger::ERR_MSG << "Error in parsing formation: format error for point."; + form->destroy(); + return 0x0; + } + } + } + } + + //normalize the formation + form->normalizeFormation(); + + return form; + } + + ///////////////////////////////////////////////////////////////////// + + FormationPtr loadFormation( const std::string & fileName ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &FreeFormation::load, FreeFormation::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No resource available."; + throw ResourceException(); + } + FreeFormation * form = dynamic_cast< FreeFormation * >( rsrc ); + if ( form == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a formation."; + throw ResourceException(); + } + + return FormationPtr( form ); + } +} // namespace Formations diff --git a/src/Plugins/Formations/FreeFormation.h b/src/Plugins/Formations/FreeFormation.h new file mode 100644 index 00000000..d1657a2d --- /dev/null +++ b/src/Plugins/Formations/FreeFormation.h @@ -0,0 +1,314 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FreeFormation.h + * @brief Implementatin of freestyle formations. + * + * An implemenatation of the paper at: + * http://graphics.cs.uh.edu/wp-content/papers/2013/2011_CGA-crowd-formation-generation-preprint.pdf + */ + +#ifndef __FREE_FORMATION_H__ +#define __FREE_FORMATION_H__ + +#include <map> +#include <vector> +#include "FSM.h" +#include "BaseAgent.h" +#include "resources/Resource.h" +#include "mengeCommon.h" +#include "PrefVelocity.h" + +using namespace Menge; + + +/*! + * @namespace Formations + * @brief The name space for the Formation Model + * + * This formation model is based off of + *http://graphics.cs.uh.edu/wp-content/papers/2013/2011_CGA-crowd-formation-generation-preprint.pdf + * + * We use input files which contain the formation coordinates to + * define a formation, and a task and velocity modifier to execute them. + */ + +namespace Formations { + + /*! + * @brief The data structure representing a point in the formation. + */ + struct FormationPoint { + size_t _id; ///< The id of the sentinel point + Vector2 _pos; ///< The position of the sentinel point (in formation space) + float _dist; ///< The distance of the sentinel point to the formation center + Vector2 _dir; ///< The direction of the sentinel point to the formation center + bool _border; ///< Flag indicating if this is a border point (true) or not (false). + float _weight; ///< The weight of the sentinel point + }; + + /*! + * @brief The class for modeling a freestyle formation. + */ + class FreeFormation : public Resource{ + public: + /*! + * @brief Constructor + * + * @param name The name of the file containing the target formation. + */ + FreeFormation(const std::string & name); + + /*! + * @brief Destructor + */ + ~FreeFormation(); + + /*! + * @brief Reports the message label for this resource. + * + * @returns The label for formations. + */ + virtual const std::string & getLabel() const { return LABEL; } + + /*! + * @brief Parses a formation definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a Formation, but to a Resource. The ResourceManager + * uses it to load and instantiateResource instances. + * + * @param fileName The path to the file containing the Formation + * definition. + * @returns A pointer to the new Formation (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + /*! + * @brief Adds an agent to this formation. + * + * Only agents "added" to the formation will be mapped considered. + * ?? What happens if more agents htan formation points are added? + * + * @param agt The agent to add to the formation. + */ + void addAgent( const Agents::BaseAgent * agt ); + + /*! + * @brief Removes an agent from the formation. + * + * @param agt The agent to remove. + */ + void removeAgent(const Agents::BaseAgent *agt); + + /*! + * @brief Computes the mapping from tracked agents to formation points. + * + * @param fsm A pointer to the FSM. + * + */ + void mapAgentsToFormation(const BFSM::FSM * fsm); + + /*! + * @brief Provides an intermediate goal for the agent. + * + * This assumes that the agent provided is a member of the formation. It only + * checks in debug mode (via an assertion). + * + * @param agt The agent for whom the goal is provided. + * @param pVel The agent's preferred velocity...does it change?? + * @param target The intermediate goal value is stored in this vector. + * @returns True if the an intermediate goal exists and is set in target, false otherwise. + */ + bool getGoalForAgent(const Agents::BaseAgent * agt, Agents::PrefVelocity &pVel, Vector2 &target); + + protected: + + /*! + * @brief Maps a single agent to a sentinel point + * + * @param agt The agent to map to a sentinel point. + * + */ + void mapAgentToPoint(const Agents::BaseAgent *agt); + + /*! + * @brief Maps a border point to one of the agents in the formation. + * + * @param pt A border point to map to an agent. + * + */ + void mapPointToAgent(FormationPoint *pt); + + /*! + * @brief Adds a point to the formation. + * + * @param pt A point (in formation space). + * @param borderPoint True if the point should be considered a border point (false otherwise). + * @param weight The weight of the point. + */ + void addFormationPoint(Vector2 pt, bool borderPoint, float weight ); + + /*! + * @brief Adds an agent to the formation. + * + * @param agt The agent to add to the formation. + */ + void addAgentPoint(const Agents::BaseAgent *agt); + + /*! + * @brief Finalize the formation representation for use. + * + * Normalizing the formation defines distances between the formation center + * and formation points relative to the *size* of the formation. This allows + * for arbitrary scales. + */ + void normalizeFormation(); + + /*! + * @brief A custom distance metric to apply to formation points. Used + * for evaluating "similarity" between formation points. + * + * @param pt1 the first point to check + * @param pt2 the other point to check + * @returns The "distance" between the two formatin points. + */ + float formationDistance( FormationPoint *pt1, FormationPoint *pt2 ); + + /*! + * @brief Maps formation point identifiers to agent identifiers. + * Why identifiers? + */ + std::map< size_t, size_t > _agent_formationPoint; + + /*! + * @brief Maps agent identifiers to formation point identifiers. + * Why identifiers? + */ + std::map< size_t, size_t > _formationPoint_agent; + + /*! + * @brief Maps agent identifiers to formation points. + * This lets me seach over a space instead of + * doing a lot of vector math each timestep + * ? WHAT ? + */ + std::map< size_t, FormationPoint * > _agentPoints; + + /*! + * @brief The formation points defining the formation. + */ + std::vector< FormationPoint * > _formationPoints; + + /*! + * @brief A separate cache of border points -- this is a subset of _formationPoints. + */ + std::vector< FormationPoint * > _borderPoints; + + /*! + * @brief The formation's direction of travel. + */ + Vector2 _direction; + + /*! + * @brief The preferred speed of the formation. + */ + float _speed; + + /*! + * @brief The location of the formation center in world space (0,0). + */ + Vector2 _pos; + + /*! + * @brief The instantaneous max distance from the center of the formation to normalized agent positions + * ?? + */ + float _agentRadius; + + /*! + * @brief A cache of previoius agent preferred directions. + * Maps agent identifiers to directions. + */ + std::map< size_t, Vector2 > _agentPrefDirs; + + /*! + * @brief A cache of previoius agent preferred velocities. + * Maps agent identifiers to velocities. + */ + std::map< size_t, Vector2 > _agentPrefVels; + + /*! + * @brief A cache of previoius agent preferred weights. + * Maps agent identifiers to weights. + * + * TODO: Currently, these are *always* 1.0. Provide mechanism + * for defininig non-unit weights. + */ + std::map< size_t, float > _agentWeights; + + /*! + * @brief A cache of previoius agent preferred directions. + * Maps agent identifiers to agents. + */ + std::map< size_t, const Agents::BaseAgent * > _agents; + }; + + /*! + * @brief The definition of the managed pointer for formation data + */ + typedef ResourcePtr< FreeFormation > FormationPtr; + + /*! + * @brief load a formation + * @param fileName The name of the file containing the formation definition. + * @returns The FormationPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ + FormationPtr loadFormation( const std::string & fileName ) throw ( ResourceException ); +}; + +#endif diff --git a/src/Plugins/FundamentalDiagram/FundamentalDiagram.cpp b/src/Plugins/FundamentalDiagram/FundamentalDiagram.cpp new file mode 100644 index 00000000..dd00e205 --- /dev/null +++ b/src/Plugins/FundamentalDiagram/FundamentalDiagram.cpp @@ -0,0 +1,76 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FundamentalDiagram.cpp + * @brief Plugin for formations + */ + +#include "FundamentalDiagramConfig.h" +#include "FundamentalDiagramModifier.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" FDMODIFIER_API const char * getName() { + return "fundamental_diagram"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" FDMODIFIER_API const char * getDescription() { + return "Velocity Modifier plugin for adherence to the Fundamental Diagram" \ + "including the following:\n"\ + "\tModifier \"fundamantal_diagram\" - adjusts the agent's preferred velocity to match the FD. " ; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" FDMODIFIER_API void registerPlugin( PluginEngine * engine ) { + engine->registerVelModFactory( new FDModifier::FDModifierFactory() ); +} + diff --git a/src/Plugins/FundamentalDiagram/FundamentalDiagramConfig.h b/src/Plugins/FundamentalDiagram/FundamentalDiagramConfig.h new file mode 100644 index 00000000..bc153986 --- /dev/null +++ b/src/Plugins/FundamentalDiagram/FundamentalDiagramConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FundamentalDiagramConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __FDMODIFIER_CONFIG_H__ +#define __FDMODIFIER_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( FDMODIFIER_STATICLIB ) + #define FDMODIFIER_API + #else + #if defined( FDMODIFIER_EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define FDMODIFIER_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define FDMODIFIER_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( FDMODIFIER_STATICLIB ) + #define FDMODIFIER_API + #else + #if defined( FDMODIFIER_EXPORT ) + #define FDMODIFIER_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define FDMODIFIER_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __FDMODIFIER_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.cpp b/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.cpp new file mode 100644 index 00000000..ff4d2f1c --- /dev/null +++ b/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.cpp @@ -0,0 +1,162 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __FORMATIONS_MODIFIER_CPP__ +#define __FORMATIONS_MODIFIER_CPP__ + +#include "FundamentalDiagramModifier.h" +#include "BaseAgent.h" +#include "Obstacle.h" + +namespace FDModifier { + ///////////////////////////////////////////////////////////////////// + // Implementation of FDModifier + ///////////////////////////////////////////////////////////////////// + + FDModifier::FDModifier(): BFSM::VelModifier(), _bufferGen(0x0), _factorGen(0x0), _sigmaAgent(1.5f), _sigmaObstacle(0.75f) { + } + + ///////////////////////////////////////////////////////////////////// + + FDModifier::FDModifier( FloatGenerator * buffer, FloatGenerator * factor, float sigmaAgent, float sigmaObstacle ): BFSM::VelModifier(), _bufferGen(buffer), _factorGen(factor), _sigmaAgent(sigmaAgent), _sigmaObstacle(sigmaObstacle) { + } + + ///////////////////////////////////////////////////////////////////// + + BFSM::VelModifier* FDModifier::copy() const{ + return new FDModifier( _bufferGen->copy(), _factorGen->copy(), _sigmaAgent, _sigmaAgent ); + }; + + ///////////////////////////////////////////////////////////////////// + + void FDModifier::adaptPrefVelocity(const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ){ + float strideConst, speedConst; + _paramLock.lock(); + HASH_MAP< size_t, FDParam >::iterator itr = _strideParams.find( agent->_id ); + if ( itr == _strideParams.end() ) { + FDParam param( _factorGen->getValue(), _bufferGen->getValue() ); + _strideParams[ agent->_id ] = param; + strideConst = param._strideConst; + speedConst = param._speedConst; + } else { + strideConst = itr->second._strideConst; + speedConst = itr->second._speedConst; + } + _paramLock.release(); + + //define temporary vars + float prefSpeed = pVel.getSpeed(); + Vector2 prefDir( pVel.getPreferred() ); + float availSpace = 1e6f; // start assuming there is infinite space + + const float testDistance = 1.f; // The distance (in meters) in the direction of preferred travel to test + // the density. + Vector2 critPt = agent->_pos + testDistance * prefDir; + + float density = 0.f; + // For now, assume some constants + const float areaSq2Inv = 1.f / ( 2 * _sigmaAgent * _sigmaAgent ); + const float sqrt2Pi = sqrtf( TWOPI ); + const float norm = 1.f / ( _sigmaAgent * sqrt2Pi ); + + // AGENTS + for ( size_t i = 0; i < agent->_nearAgents.size(); ++i ) { + const Agents::BaseAgent* const other = agent->_nearAgents[i].agent; + Vector2 critDisp = other->_pos - critPt; + Vector2 yComp = ( critDisp * prefDir ) * prefDir; // dot project gets projection, in the preferred direction + Vector2 xComp = ( critDisp - yComp ) * 2.5f; // penalize displacement perpindicular to the preferred direction + critDisp.set( xComp + yComp ); + float distSq = absSq( critDisp ); + density += norm * expf( -distSq * areaSq2Inv ); + } + + //// OBSTACLES + const float OBST_AREA_SQ_INV = 1.f / ( 2 * _sigmaObstacle * _sigmaObstacle ); + const float OBST_NORM = 1.f / ( _sigmaObstacle * sqrt2Pi ); + const float OBST_SCALE = norm;// * 6.25f; // what is the "density" of an obstacle? + for ( size_t i = 0; i < agent->_nearObstacles.size(); ++i ) { + const Agents::Obstacle* const obst = agent->_nearObstacles[i].obstacle; + Vector2 nearPt; + float distSq; // set by distanceSqToPoint + if ( obst->distanceSqToPoint( critPt, nearPt, distSq ) == Agents::Obstacle::LAST ) continue; + + if ( ( nearPt - agent->_pos ) * prefDir < 0.f ) continue; + density += OBST_SCALE * expf( -distSq * OBST_AREA_SQ_INV ); + } + + const float AGENT_WIDTH = 0.48f; + if ( density < 0.001f ) { + availSpace = 100.f; + } else { + availSpace = AGENT_WIDTH / density ; + } + + // Compute the maximum speed I could take for the available space + float maxSpeed = speedConst * availSpace * availSpace; + if ( maxSpeed < prefSpeed ) pVel.setSpeed( maxSpeed ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of FDModFactory + ///////////////////////////////////////////////////////////////////// + + FDModifierFactory::FDModifierFactory():BFSM::VelModFactory() { + _factorID = _attrSet.addFloatDistAttribute( "factor_", true, 0.f, 1.f ); + _bufferID = _attrSet.addFloatDistAttribute( "buffer_", true, 0.f, 1.f ); + _sigmaAgentID = _attrSet.addFloatAttribute( "sigma_agent", false, 1.5f ); + _sigmaObstacleID = _attrSet.addFloatAttribute( "sigma_obstacle", false, 0.75f ); + } + + ///////////////////////////////////////////////////////////////////// + + bool FDModifierFactory::setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const { + FDModifier * FDMod = dynamic_cast<FDModifier *>( modifier ); + assert( FDMod != 0x0 && "Trying to set property modifier properties on an incompatible object" ); + + if ( ! BFSM::VelModFactory::setFromXML( modifier, node, behaveFldr ) ) return false; + + //set the params we need + FDMod->setBuffer( _attrSet.getFloatGenerator( _bufferID ) ); + FDMod->setFactor( _attrSet.getFloatGenerator( _factorID ) ); + FDMod->setSigmaAgent( _attrSet.getFloat( _sigmaAgentID ) ); + FDMod->setSigmaObstacle( _attrSet.getFloat( _sigmaObstacleID ) ); + return true; + } +}; + +#endif diff --git a/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.h b/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.h new file mode 100644 index 00000000..9e592a30 --- /dev/null +++ b/src/Plugins/FundamentalDiagram/FundamentalDiagramModifier.h @@ -0,0 +1,290 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file FundamentalDiagramModifier.h + * @brief Definiton of a Velocity Modifier to enforce FD adherance + * + * Uses the model presented in http://gamma.cs.unc.edu/DenseSense/. + */ +#ifndef __FDMODIFIER_MODIFIER_H__ +#define __FDMODIFIER_MODIFIER_H__ + +#include "FundamentalDiagramConfig.h" +#include "VelocityModifiers/VelModifier.h" +#include "VelocityModifiers/VelModifierFactory.h" +#include "FSMEnumeration.h" +#include "SimpleLock.h" +#include "mengeCommon.h" + +using namespace Menge; + +/*! + * @namespace FDModifier + * @brief The name space for the Fundamental Diagram adherence model + * + * This namespace contains a velocity modifier which varies preferred speed based on local density conditions. + */ +namespace FDModifier { + + class FDModifierFactory; + + /*! + * @brief Velocity modifier that adapts preferred velocity to account + * for local density. This produces a density-dependent behavior + * which can conform to the fundamental diagram (depending on the + * settings.) + */ + class FDMODIFIER_API FDModifier : public BFSM::VelModifier { + public: + + /*! + * @brief Constructor. + */ + FDModifier(); + + /*! + * @brief Constructor. + * + * @param buffer The stride buffer gemerator. This modifier takes ownership + * of the provided generator. + * @param factor The stride factor gemerator. This modifier takes ownership + * of the provided generator. + * @param sigmaAgent Sigma for agent density estimation + * @param sigmaObstacle Sigma for obstacle density estimation + */ + FDModifier( FloatGenerator * buffer, FloatGenerator * factor, float sigmaAgent, float sigmaObstacle ); + + /*! + * @brief Copy method for this velocity modifier. + */ + BFSM::VelModifier* copy() const; + + /*! + * @brief Adapts the given agent's preferred velocity to adhere to the fundamental diagram. + * + * @param agent The agent on whom we are operating. + * @param pVel The input preferred velocity of the agent. + */ + void adaptPrefVelocity( const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ); + + /*! + * @brief Sets the stride buffer. + * + * @param buffer The stride buffer for the adherence model + */ + void setBuffer( FloatGenerator * buffer) { if ( _bufferGen ) delete _bufferGen; _bufferGen = buffer; } + + /*! + * @brief Sets the stride factor. + * + * @param factor The stride factor for the adherence model + */ + void setFactor( FloatGenerator * factor ) {if ( _factorGen ) delete _factorGen; _factorGen = factor; } + + /*! + * @brief Sets the agent sigma. + * + * @param sigma Sigma for agent density estimation + */ + void setSigmaAgent( float sigma ) { _sigmaAgent = sigma; } + + /*! + * @brief Sets the agent sigma. + * + * @param sigma Obstacle sigma for Probability Density Estimation + */ + void setSigmaObstacle( float sigma ) { _sigmaObstacle = sigma; } + + friend class FDModifierFactory; + + protected: + /*! + * @brief Defines the parameters which define the + * density-aware behavior. + */ + struct FDParam { + /*! + * @brief Default constructor + */ + FDParam() : _strideConst(1.f), _speedConst(1.f) {} + + /*! + * @brief Constructor. + * + * @param factor The stride factor. + * @param buffer The stride buffer. + */ + FDParam( float factor, float buffer ) { + _strideConst = 0.5f * ( 1.f + buffer ) / factor ; + _speedConst = 1.f / ( _strideConst * _strideConst ); + } + + /*! + * @brief One of two derived constants for fundamental diagram compliance. + * This is a function of the stride factor and stride buffer + */ + float _strideConst; + + /*! + * @brief The second of two derived constants for fundamental diagram compliance. + * This is a function of the stride factor and stride buffer + */ + float _speedConst; + }; + + /*! + * @brief The readers-writer lock to preserve thread-safety + * on _strideParams. + */ + SimpleLock _paramLock; + + /*! + * @brief The per-agent parameters. + */ + HASH_MAP< size_t, FDParam > _strideParams; + + /*! + * @brief The Stride buffer value generator. + */ + FloatGenerator * _bufferGen; + + /*! + * @brief The Stride factor value generator. + */ + FloatGenerator * _factorGen; + + /*! + * @brief Agent sigma for density calculation + */ + float _sigmaAgent; + + /*! + * @brief Sigma for obstacle density estimation + */ + float _sigmaObstacle; + }; + + //////////////////////////////////////////////////////////////////////// + + /*! + * @brief The factory for the FDModifier class. + */ + class FDMODIFIER_API FDModifierFactory : public BFSM::VelModFactory { + public: + /*! + * @brief Constructor. + */ + FDModifierFactory(); + + /*! + * @brief The name of the modifier + * + * The modifier's name must be unique among all registered modifier. + * Each modifier factory must override this function. + * + * @returns A string containing the unique modifier name. + */ + virtual const char * name() const { return "fundamental_diagram"; } + + /*! + * @brief A description of the modifier + * + * Each modifier factory must override this function. + * + * @returns A string containing the modifier description. + */ + virtual const char * description() const { + return "Adjusts the agent's preferred speed to adhere to the fundamental diagram "; + }; + + protected: + /*! + * @brief Create an instance of this class's modifier. + * + * All modifierFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding modifier type. The various field values + * of the instance will be set in a subsequent call to modifierFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated modifier class. + */ + BFSM::VelModifier * instance() const { return new FDModifier(); } + + /*! + * @brief Given a pointer to an modifier instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this modifier's type. + * (i.e. modifierFactory::thisFactory has already been called and returned true.) + * If sub-classes of modifierFactory introduce *new* modifier parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param modifier A pointer to the modifier whose attributes are to be set. + * @param node The XML node containing the modifier attributes. + * @param behaveFldr The path to the behavior file. If the modifier references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "stride_buffer" float attribute + */ + size_t _bufferID; + + /*! + * @brief The identifier for the "stride_factor" float attribute + */ + size_t _factorID; + + /*! + * @brief The identifier for the "sigma_agent" float attribute + */ + size_t _sigmaAgentID; + + /*! + * @brief The identifier for the "sigma_obstacle" float attribute + */ + size_t _sigmaObstacleID; + }; +}; +#endif // __FDMODIFIER_MODIFIER_H__ diff --git a/src/Plugins/SampleProjectTemplate/SampleConfig.h b/src/Plugins/SampleProjectTemplate/SampleConfig.h new file mode 100644 index 00000000..352ede7a --- /dev/null +++ b/src/Plugins/SampleProjectTemplate/SampleConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SampleConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __SAMPLE_CONFIG_H__ +#define __SAMPLE_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define EXPORT_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define EXPORT_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + #define EXPORT_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define EXPORT_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __SAMPLE_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/SampleProjectTemplate/SamplePlugin.cpp b/src/Plugins/SampleProjectTemplate/SamplePlugin.cpp new file mode 100644 index 00000000..10ff6f18 --- /dev/null +++ b/src/Plugins/SampleProjectTemplate/SamplePlugin.cpp @@ -0,0 +1,75 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file SamplePlugin.cpp + * @brief Plugin for extended elements. + */ + +#include "SampleConfig.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" EXPORT_API const char * getName() { + return "Unique plugin name"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" EXPORT_API const char * getDescription() { + return "Appropriate overal description followed by details:\n"\ + "\tFeature 1\n" + "\tFeature 2\n" + "\tetc."; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" EXPORT_API void registerPlugin( PluginEngine * engine ) { +} + diff --git a/src/Plugins/Terrain/ElevationHeightField.cpp b/src/Plugins/Terrain/ElevationHeightField.cpp new file mode 100644 index 00000000..9089f9d6 --- /dev/null +++ b/src/Plugins/Terrain/ElevationHeightField.cpp @@ -0,0 +1,112 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "ElevationHeightField.h" +#include "BaseAgent.h" +#include "tinyxml.h" +#include "os.h" + +namespace Terrain { + + //////////////////////////////////////////////////////////////// + // Implementation of HeightFieldElevation + //////////////////////////////////////////////////////////////// + + HeightFieldElevation::HeightFieldElevation(): Agents::Elevation(), _field(0x0) { + } + + //////////////////////////////////////////////////////////////// + + float HeightFieldElevation::getElevation( const Vector2 & point ) const { + return _field->getHeightAt( point._x, point._y ); + } + + //////////////////////////////////////////////////////////////// + + float HeightFieldElevation::getElevation( const Agents::BaseAgent * agent ) const { + return _field->getHeightAt( agent->_pos._x, agent->_pos._y ); + } + + //////////////////////////////////////////////////////////////// + + Vector2 HeightFieldElevation::getGradient( const Agents::BaseAgent * agent ) const { + Vector3 norm = _field->getNormalAt( agent->_pos._x, agent->_pos._y ); + return Vector2( norm._x, norm._z ); + } + + //////////////////////////////////////////////////////////////// + + Vector2 HeightFieldElevation::getGradient( const Vector2 & point ) const { + Vector3 norm = _field->getNormalAt( point._x, point._y ); + return Vector2( norm._x, norm._z ); + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of HeightFieldElevationFactory + ///////////////////////////////////////////////////////////////////// + + HeightFieldElevationFactory::HeightFieldElevationFactory() : Agents::ElevationFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + } + + ///////////////////////////////////////////////////////////////////// + + bool HeightFieldElevationFactory::setFromXML( Agents::Elevation * e, TiXmlElement * node, const std::string & specFldr ) const { + HeightFieldElevation * hfe = dynamic_cast< HeightFieldElevation * >( e ); + assert( hfe != 0x0 && "Trying to set attributes of a height field elevation component on an incompatible object" ); + + if ( ! ElevationFactory::setFromXML( hfe, node, specFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, specFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + // nav mesh + HeightFieldPtr hfPtr; + try { + hfPtr = loadHeightField( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the height field elevation referenced on line " << node->Row() << "."; + return false; + } + hfe->setHeightField( hfPtr ); + + return true; + } + +} // namespace Terrain diff --git a/src/Plugins/Terrain/ElevationHeightField.h b/src/Plugins/Terrain/ElevationHeightField.h new file mode 100644 index 00000000..d6231d40 --- /dev/null +++ b/src/Plugins/Terrain/ElevationHeightField.h @@ -0,0 +1,204 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file ElevationHeightField.h + * @brief Defines elevation based on a height field. If + * an agent (or a point) cannot be located on the field, its + * elevation is ???? + */ + + +#ifndef __ELEVATION_HEIGHT_FIELD_H__ +#define __ELEVATION_HEIGHT_FIELD_H__ + +// Resources +#include "HeightField.h" + +// Menge Base +#include "Elevations/Elevation.h" +#include "Elevations/ElevationFactory.h" + +// forward declaration +namespace Menge { + namespace Agents { + class BaseAgent; + } +} + +using namespace Menge; + +/*! + * @namespace Terrain + * @brief The namespace containing the height field resource and Menge elements + * which use the height field. + */ +namespace Terrain { + + /*! + * @brief Elevation definition based on a height field. + */ + class EXPORT_API HeightFieldElevation : public Agents::Elevation { + public: + /*! + * @brief Constructor + */ + HeightFieldElevation(); + + /*! @brief Reports the elevation of the simulation domain at the given point. + * The domain may have more than one valid elevation for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The elevation at the given point. + */ + virtual float getElevation( const Vector2 & point ) const; + + /*! + * @brief Reports the elevation of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which elevation should be reported. + * @returns The elevation (position on the y-axis) based on current agent state/position. + */ + virtual float getElevation( const Agents::BaseAgent * agent ) const; + + /*! @brief Reports the gradient of the simulation domain at the given point. + * The domain may have more than one valid gradient for the point. + * It is the responsibility of the elevation entity resolve this. + * + * @param point A point on the x-z cartesian plane. + * @returns The gradient at the given point. + */ + virtual Vector2 getGradient( const Vector2 & point ) const; + + /*! + * @brief Reports the gradient of the simulation domain for the given agent + * + * @param agent A pointer to the agent for which gradient should be reported. + * @returns The gradient of the domain based on current agent state/position. + */ + virtual Vector2 getGradient( const Agents::BaseAgent * agent ) const; + + /*! + * @brief Sets the height field for this elevation object to use. + * + * @param hfPtr A managed pointer to the height field. + */ + void setHeightField( HeightFieldPtr hfPtr ) { _field = hfPtr; } + + protected: + /*! + * @brief The height field used to query elevation and gradient + */ + HeightFieldPtr _field; + }; + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the HeightFieldElevation. + */ + class EXPORT_API HeightFieldElevationFactory : public Agents::ElevationFactory { + public: + /*! + * @brief Constructor. + */ + HeightFieldElevationFactory(); + + /*! + * @brief The name of the elevation. + * + * The elevation's name must be unique among all registered elevation components. + * Each elevation factory must override this function. + * + * @returns A string containing the unique elevation name. + */ + virtual const char * name() const { return "height_field"; } + + /*! + * @brief A description of the elevation. + * + * Each elevation factory must override this function. + * + * @returns A string containing the elevation description. + */ + virtual const char * description() const { + return "Provides elevation based on location on a height field."; + }; + + protected: + /*! + * @brief Create an instance of this class's elevation implementation. + * + * All ElevationFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding elevation type. The various field values + * of the instance will be set in a subsequent call to ElevationFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Elevation class. + */ + Agents::Elevation * instance() const { return new HeightFieldElevation(); } + + /*! + * @brief Given a pointer to an Elevation instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Elevation's type. + * (i.e. ElevationFactory::thisFactory has already been called and returned true.) + * If sub-classes of ElevationFactory introduce *new* Elevation parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param e A pointer to the elevation whose attributes are to be set. + * @param node The XML node containing the elevation attributes. + * @param specFldr The path to the specification file. If the Elevation references + * resources in the file system, it should be defined relative + * to the specification file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( Agents::Elevation * e, TiXmlElement * node, const std::string & specFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + }; +} // namespace Terrain +#endif // __ELEVATION_HEIGHT_FIELD_H__ + diff --git a/src/Plugins/Terrain/HeightField.cpp b/src/Plugins/Terrain/HeightField.cpp new file mode 100644 index 00000000..9d20a94f --- /dev/null +++ b/src/Plugins/Terrain/HeightField.cpp @@ -0,0 +1,430 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "HeightField.h" +#include "image.h" +#include "tinyxml.h" +#include "os.h" +#include <cmath> + +#ifdef _WIN32 +#define MIN min +#else +#define MIN std::min +#endif + +namespace Terrain { + + /////////////////////////////////////////////////////////////////////////// + // IMPLEMENTATION FOR HeightField + /////////////////////////////////////////////////////////////////////////// + + const std::string HeightField::LABEL("height_field"); + + /////////////////////////////////////////////////////////////////////////// + + HeightField::HeightField( const std::string & fileName ) : Resource(fileName), _cellSize(1.f), _W(0), _H(0), _heightMap(0x0), _normalMap(0x0), _xpos(0.f), _ypos(0.f) { + } + + /////////////////////////////////////////////////////////////////////////// + + HeightField::~HeightField() + { + for (int i=0; i<_W; i++) + { + delete[] _heightMap[i]; + delete[] _normalMap[i]; + } + delete[] _heightMap; + delete[] _normalMap; + } + + /////////////////////////////////////////////////////////////////////////// + + bool HeightField::initialize(const std::string & imgName, float cellSize, float vertScale, float xpos, float zpos, float smoothParam ) { + _cellSize = cellSize; + _xpos = xpos; + _ypos = zpos; + + // TODO: Catch errors and exceptions + Image *img = loadImage( imgName ); + if ( img == 0x0 ) { + logger << Logger::ERR_MSG << "Unable to load height field image " << imgName << "."; + return false; + } + + _W = img->data()->getWidth(); + _H = img->data()->getHeight(); + + // TODO: + // Do this in one block of contiguous memory + _heightMap = new float*[ _W ]; + _normalMap = new Vector3*[ _W ]; + + for ( int x = 0; x < _W; x++ ) { + _heightMap[ x ] = new float[ _H ]; + _normalMap[ x ] = new Vector3[ _H ]; + } + + const float VSCALE = vertScale / 255.f; + for (int x = 0; x < _W; x++ ) { + for (int z = 0; z < _H; z++ ) { + _heightMap[ x ][ z ] = img->data()->getPixelAt( x, z ) * VSCALE; + } + } + + if ( smoothParam > 0.f ) { + smoothElevation( smoothParam ); + } + + computeNormals(); + + return true; + } + + /////////////////////////////////////////////////////////////////////////// + + Resource * HeightField::load( const std::string & fileName ) { + // Open the XML + TiXmlDocument xml( fileName ); + bool loadOkay = xml.LoadFile(); + + if ( !loadOkay ) { // load xml file + logger << Logger::ERR_MSG << "Could not load height field configuration xml (" << fileName << ") due to xml syntax errors.\n"; + logger << "\t" << xml.ErrorDesc(); + return false; + } + + TiXmlElement* rootNode = xml.RootElement(); + if( ! rootNode ) { + logger << Logger::ERR_MSG << "Height field configuration (" << fileName << ") does not contain a root element."; + return false; + } + + if( rootNode->ValueStr () != "HeightField" ) { + logger << Logger::ERR_MSG << "Height field configuration (" << fileName << ")'s root element is not \"HeightField\"."; + return false; + } + + std::string absPath; + os::path::absPath( fileName, absPath ); + std::string junk; + std::string sceneFldr; + os::path::split( absPath, sceneFldr, junk ); + + std::string imgName; + double d; + float cellSize, vertScale, xPos, yPos, smooth; + bool valid = true; + + const char * nameCStr = rootNode->Attribute( "file_name" ); + if ( nameCStr == 0x0 ) { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"file_name\" attribute."; + valid = false; + } + imgName = nameCStr; + + if ( rootNode->Attribute( "cell_size", &d ) ) { + cellSize = (float)d; + } else { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"cell_size\" attribute."; + valid = false; + } + + if ( rootNode->Attribute( "vert_scale", &d ) ) { + vertScale = (float)d; + } else { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"vert_scale\" attribute."; + valid = false; + } + + if ( rootNode->Attribute( "x", &d ) ) { + xPos = (float)d; + } else { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"x\" attribute."; + valid = false; + } + + if ( rootNode->Attribute( "y", &d ) ) { + yPos = (float)d; + } else { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"y\" attribute."; + valid = false; + } + + if ( rootNode->Attribute( "kernel", &d ) ) { + smooth = (float)d; + } else { + logger << Logger::ERR_MSG << "The HeightField definition " << fileName << " is missing the required \"kernel\" attribute."; + valid = false; + } + + if ( valid ) { + HeightField * hf = new HeightField( fileName ); + if ( ! hf->initialize( os::path::join( 2, sceneFldr.c_str(), imgName.c_str() ), cellSize, vertScale, xPos, yPos, smooth ) ) { + //if ( ! hf->initialize( imgName, cellSize, vertScale, xPos, yPos, smooth ) ) { + hf->destroy(); + return 0x0; + } + return hf; + } else { + logger << Logger::ERR_MSG << "No height field instantiated from " << fileName << "."; + return 0x0; + } + } + + /////////////////////////////////////////////////////////////////////////// + + void HeightField::computeNormals() { + const float DELTA = 2 * _cellSize; + + for ( int x = 0; x < _W; x++ ) { + for ( int y = 0; y < _H; y++ ) { + Vector3 Nx; + if ( x == 0 ) { + float dh = _heightMap[ x + 1 ][ y ] - _heightMap[ x ][ y ]; + Nx.set( _cellSize, -dh, 0.f ); + } else if ( x == _W - 1 ) { + float dh = _heightMap[ x ][ y ] - _heightMap[ x - 1 ][ y ]; + Nx.set( _cellSize, -dh, 0.f ); + } else { + float dh = _heightMap[ x + 1 ][ y ] - _heightMap[ x - 1 ][ y ]; + Nx.set( DELTA, -dh, 0.f ); + } + + Vector3 Ny; + if ( y == 0 ) { + float dh = _heightMap[ x ][ y + 1 ] - _heightMap[ x ][ y ]; + Ny.set( 0.f, -dh , _cellSize); + } else if ( y == _H - 1 ) { + float dh = _heightMap[ x ][ y ] - _heightMap[ x ][ y - 1 ]; + Ny.set( 0.f, -dh , _cellSize); + } else { + float dh = _heightMap[ x ][ y + 1 ] - _heightMap[ x ][ y - 1 ]; + Ny.set( 0.f, -dh , DELTA); + } + Vector3 norm( Ny.cross( Nx ) ); + norm.normalize(); + //Nx.normalize(); + //Ny.normalize(); + _normalMap[ x ][ y ].set( Vector3( -norm._x, norm._y, -norm._z ) ); + //_normalMap[ x ][ y ].set( norm ); + //_normalMap[ x ][ y ].set( Ny.cross( Nx ) ); + } + } + } + + /////////////////////////////////////////////////////////////////////////// + + float HeightField::getHeightAtCell( int x, int y ) const { + return _heightMap[x][y]; + } + + /////////////////////////////////////////////////////////////////////////// + + Vector3 HeightField::getNormalAtCell( int x, int y ) const { + return _normalMap[x][y]; + } + + /////////////////////////////////////////////////////////////////////////// + + float HeightField::getHeightAt( float x, float y ) const { + x = (x - _xpos) / _cellSize; + y = (y - _ypos) / _cellSize; + + if ( ( x < 0 ) || ( y < 0 ) || ( x > _W-1 ) || ( y > _H-1 ) ) { return 0.f; } + + int x1 = (int)floor(x); + int y1 = (int)floor(y); + int x2 = MIN(_W-1, x1+1); + int y2 = MIN(_H-1, y1+1); + + float f11 = _heightMap[x1][y1]; + float f12 = _heightMap[x1][y2]; + float f21 = _heightMap[x2][y1]; + float f22 = _heightMap[x2][y2]; + + x -= x1; + y -= y1; + + float res = f11*(1-x)*(1-y) + f21*x*(1-y) + f12*(1-x)*y + f22*x*y; + return res; + } + + /////////////////////////////////////////////////////////////////////////// + + Vector3 HeightField::getNormalAt( float x, float y ) const { + x -= _xpos; + y -= _ypos; + int X = (int)( x / _cellSize ); + int Y = (int)( y / _cellSize ); + if ( X < 0 ) X = 0; + else if ( X >= _W ) X = _W - 1; + if ( Y < 0 ) Y = 0; + else if ( Y >= _H ) Y = _H - 1; + return _normalMap[ X ][ Y ]; + } + + /////////////////////////////////////////////////////////////////////////// + + void HeightField::smoothElevation( float smooth ) { + // Compute the kernel size + int cellCount = (int)(( 6.f * smooth ) / _cellSize + 0.5f ); + if ( cellCount % 2 == 0 ) ++cellCount; + // compute the kernel + float * kernel = new float[ cellCount ]; + int halfCount = cellCount / 2; + int cell = -halfCount; + float sum = 0.f; + float denom = 1.f / ( 2 * smooth * smooth ); + for ( int i = 0; i < cellCount; ++i, ++cell ) { + float x = cell * _cellSize; + kernel[ i ] = exp( -x * x * denom ); + sum += kernel[ i ]; + } + // normalize + denom = 1.f / sum; + for ( int i = 0; i < cellCount; ++i ) { + kernel[ i ] *= denom; + } + + // Normalization factors for one-sided kernels + // normFactor[ i ] is what I should multiply the convolved value when the kernel + // is centered either on index i, or END_VALUE - (i + 1). + float * normFactors = new float[ halfCount ]; + for ( int i = 0; i < halfCount; ++i ) { + float sum = 0.f; + for ( int j = halfCount - i; j < cellCount; ++j ) { + sum += kernel[ j ]; + } + normFactors[i] = 1.f / sum; + } + + // Prepare to convolve + float * workSpace = new float[ _W > _H ? _W : _H ]; + // iterate along width axis + int SIZE = _W; + for ( int strip = 0; strip < _H; ++strip ) { + for ( int center = 0; center < SIZE; ++center ) { + // convolve data + float sum = 0.f; + if ( center >= halfCount && center < SIZE - halfCount ) { + int i = 0; + for ( int k = center - halfCount; k < center + halfCount + 1; ++k, ++i ) { + sum += _heightMap[ k ][ strip ] * kernel[ i ]; + } + } else if ( center < halfCount ) { + // Truncated kernel on the left + int i = halfCount - center; + for ( int k = 0; k <= center + halfCount; ++k, ++i ) { + sum += _heightMap[ k ][ strip ] * kernel[ i ]; + } + sum *= normFactors[ center ]; + } else { + // Truncated kernel on the right + int i = 0; + for ( int k = center - halfCount; k < SIZE; ++k, ++i ) { + sum += _heightMap[ k ][ strip ] * kernel[ i ]; + } + sum *= normFactors[ SIZE - 1 - center ]; + } + workSpace[ center ] = sum; + } + // recopy data + for ( int center = 0; center < SIZE; ++center ) { + _heightMap[ center ][ strip ] = workSpace[ center ]; + } + } + + // iterate along the other axis + + SIZE = _H; + for ( int strip = 0; strip < _H; ++strip ) { + for ( int center = 0; center < SIZE; ++center ) { + // convolve data + float sum = 0.f; + if ( center >= halfCount && center < SIZE - halfCount ) { + int i = 0; + for ( int k = center - halfCount; k < center + halfCount + 1; ++k, ++i ) { + sum += _heightMap[ strip ][ k ] * kernel[ i ]; + } + } else if ( center < halfCount ) { + // Truncated kernel on the left + int i = halfCount - center; + for ( int k = 0; k <= center + halfCount; ++k, ++i ) { + sum += _heightMap[ strip ][ k ] * kernel[ i ]; + } + sum *= normFactors[ center ]; + } else { + // Truncated kernel on the right + int i = 0; + for ( int k = center - halfCount; k < SIZE; ++k, ++i ) { + sum += _heightMap[ strip ][ k ] * kernel[ i ]; + } + sum *= normFactors[ SIZE - 1 - center ]; + } + workSpace[ center ] = sum; + } + // recopy data + for ( int center = 0; center < SIZE; ++center ) { + _heightMap[ strip ][ center ] = workSpace[ center ]; + } + } + + delete [] kernel; + delete [] normFactors; + delete [] workSpace; + } + + ////////////////////////////////////////////////////////////////////////////////////// + + HeightFieldPtr loadHeightField( const std::string & fileName ) throw ( ResourceException ) { + Resource * rsrc = ResourceManager::getResource( fileName, &HeightField::load, HeightField::LABEL ); + if ( rsrc == 0x0 ) { + logger << Logger::ERR_MSG << "No height field resource available."; + throw ResourceException(); + } + HeightField * hf = dynamic_cast< HeightField * >( rsrc ); + if ( hf == 0x0 ) { + logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a height field."; + throw ResourceException(); + } + return HeightFieldPtr( hf ); + } + +} // namespace Terrain diff --git a/src/Plugins/Terrain/HeightField.h b/src/Plugins/Terrain/HeightField.h new file mode 100644 index 00000000..9a27d611 --- /dev/null +++ b/src/Plugins/Terrain/HeightField.h @@ -0,0 +1,262 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#ifndef __HEIGHTFIELD_H__ +#define __HEIGHTFIELD_H__ + +/*! + * @file HeightField.h + * @brief Definition of a height field based on a uniform discretization of space. + */ + +#include "TerrainConfig.h" +#include "Resource.h" +#include "graphCommon.h" +#include <string> + +using namespace Menge; + +namespace Terrain { + /*! + * @brief A heightfield. A uniform discretization of space which supports queries on + * height and normal of field. + */ + class EXPORT_API HeightField : public Resource { + public: + /*! + * @brief Constructor. + * + * @param fileName The height field specification file used to define the height field. + */ + HeightField( const std::string & fileName ); + + protected: + /*! + * @brief Destructor + */ + ~HeightField(); + + public: + /*! + * @brief Initialize the height field. The heightfield is positioned with the "minimum" corner at + * the origin and extending into the first quadrant of the x-z plane + * based on cell size and image resolution. + * + * @param imgName The image file used to define the height field. + * @param cellSize The size of each cell in the image in world coordinates. + * @param vertScale The values of the image (in the range [0, 255] are normalized + * to the range [0, 1] and then multiplied by this vertical scale. + * @param xpos The x-coordinate of the terrain's origin + * @param zpos The z-coordinate of the terrain's origin + * @param smoothParam The smoothing parameter for the elevation values. It is interpreted as + * the standard deviation of a 2D symmetric gaussian kernel. If zero, + * no smoothing will be performed. + * @returns true if initalization was successful + */ + bool initialize( const std::string & imgName, float cellSize, float vertScale, float xpos, float zpos, float smoothParam=0.f ); + + /*! + * @brief Returns a unique resource label to be used to identify + * different resource *types* which use the same underlying + * file data. + */ + virtual const std::string & getLabel() const { return LABEL; } + + /*! + * @brief Parses a graph definition and returns a pointer to it. + * + * This function works in conjunction with the ResourceManager. That is why it + * returns a pointer, not to a Graph, but to a Resource. The ResourceManager + * uses it to load and instantiate Graph instances. + * + * @param fileName The path to the file containing the VectorField + * definition. + * @returns A pointer to the new Graph (if the file is valid), NULL if + * invalid. + */ + static Resource * load( const std::string & fileName ); + + /*! + * @brief Given the height field information, computes normals for + * the data. + */ + void computeNormals(); + + /*! + * @brief Returns the height at the given world position. If the world position lies + * outside of the domain of the height field, the height at the nearest cell + * center is returned. + * + * @param x The position along the x-axis. + * @param y The position along the y-axis. + * @returns The height at the position (x, y). + */ + float getHeightAt( float x, float y ) const; + + /*! + * @brief Returns the height field normal at the given world position. If the world position lies + * outside of the domain of the height field, the normal of the nearest cell + * center is returned. + * + * @param x The position along the x-axis. + * @param y The position along the y-axis. + * @returns The normal at the position (x, y). + */ + Vector3 getNormalAt( float x, float y ) const; + + /*! + * @brief Returns the height at the given cell center. + * The behavior is undefined if the indices fall outside the array of cell values. + * + * @param x The index along the x-axis.. + * @param y The index along the y-axis. + * @returns The height at the cell center with indices[ x, y ]. + */ + float getHeightAtCell( int x, int y ) const; + + /*! + * @brief Returns the normal at the given cell center. + * The behavior is undefined if the indices fall outside the array of cell values. + * + * @param x The index along the x-axis.. + * @param y The index along the y-axis. + * @returns The normal at the cell center with indices[ x, y ]. + */ + Vector3 getNormalAtCell( int x, int y ) const; + + /*! + * @brief Return the number of cells in the width direction of the field. + * + * @returns The number of cells in the width (x) direction. + */ + int getW() const { return _W; } + + /*! + * @brief Return the number of cells in the height direction of the field. + * + * @returns The number of cells in the height (y) direction. + */ + int getH() const { return _H; } + + /*! + * @brief Returns the cellSize of the height field. + * + * @returns The size of the side of the square cell. + */ + float getCellSize() const { return _cellSize; } + + /*! + * @brief Returns the x-position of the mininum corner of the grid. + * + * @returns The minimum corner of the grid. + */ + float getCornerX() const { return _xpos; } + + /*! + * @brief Returns the y-position of the mininum corner of the grid. + * + * @returns The minimum corner of the grid. + */ + float getCornerY() const { return _ypos; } + + /*! + * @brief The unique label for this data type to be used with + * resource management. + */ + static const std::string LABEL; + + protected: + /*! + * @brief Smooth the elevation using a symmetric 2D gaussian kernel. + * + * @param smooth The smoothing parameter (standard deviation) of the + * kernel. + */ + void smoothElevation( float smooth ); + + /*! + * @brief The size of a cell in the heightfield (in world coordinates) + */ + float _cellSize; + + /*! + * @brief The number of cells in the width (x) direction. + */ + int _W; + + /*! + * @brief The number of cells in the height (z) direction. + */ + int _H; + + /*! + * @brief The data for the height field. + */ + float **_heightMap; + + /*! + * @brief The data for the normals of the height field. + */ + Vector3 **_normalMap; + + /*! + * @brief The x-position of the minimum corner of the heightfield. + */ + float _xpos; + + /*! + * @brief The y-position of the minimum corner of the heightfield. + */ + float _ypos; + }; + +/*! + * @brief The definition of the managed pointer for HeightField data + */ +typedef ResourcePtr< HeightField > HeightFieldPtr; + +/*! + * @brief Loads the height field of the given name + * + * @param fileName The name of the file containing the height field. + * @returns The HeightFieldPtr containing the data. + * @throws A ResourceException if the data is unable to be instantiated. + */ +HeightFieldPtr loadHeightField( const std::string & fileName ) throw ( ResourceException ); +} // namespace Terrain +#endif \ No newline at end of file diff --git a/src/Plugins/Terrain/Terrain.cpp b/src/Plugins/Terrain/Terrain.cpp new file mode 100644 index 00000000..b403ce22 --- /dev/null +++ b/src/Plugins/Terrain/Terrain.cpp @@ -0,0 +1,79 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Terrain.cpp + * @brief Plugin for height-field-based elements. + */ + +#include "TerrainConfig.h" +#include "ElevationHeightField.h" +#include "VelModHeightField.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" EXPORT_API const char * getName() { + return "Terrain_utils"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" EXPORT_API const char * getDescription() { + return "Simulation elements based on a height field including:\n" \ + "\tElevation element\n"\ + "\tHeightField resource\n"\ + "\tHeightField velocity modifier"; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" EXPORT_API void registerPlugin( PluginEngine * engine ) { + engine->registerElevationFactory( new Terrain::HeightFieldElevationFactory() ); + engine->registerVelModFactory( new Terrain::HeightFieldModifierFactory() ); +} + diff --git a/src/Plugins/Terrain/TerrainConfig.h b/src/Plugins/Terrain/TerrainConfig.h new file mode 100644 index 00000000..01cc7475 --- /dev/null +++ b/src/Plugins/Terrain/TerrainConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file TerrainConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __TERRAIN_CONFIG_H__ +#define __TERRAIN_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define EXPORT_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define EXPORT_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + #define EXPORT_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define EXPORT_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __TERRAIN_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/Terrain/VelModHeightField.cpp b/src/Plugins/Terrain/VelModHeightField.cpp new file mode 100644 index 00000000..86588932 --- /dev/null +++ b/src/Plugins/Terrain/VelModHeightField.cpp @@ -0,0 +1,131 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "VelModHeightField.h" +#include "BaseAgent.h" +#include "tinyxml.h" +#include "os.h" + + +namespace Terrain { + + //////////////////////////////////////////////////////////////// + // Implementation of HeightFieldVelModifier + //////////////////////////////////////////////////////////////// + + HeightFieldModifier::HeightFieldModifier(): BFSM::VelModifier(), _field(0x0), _turnWeight(1.f), _upHillScale(1.f), _downHillScale(1.f) { + } + + + //////////////////////////////////////////////////////////////// + + HeightFieldModifier::HeightFieldModifier( HeightFieldPtr hfPtr ): BFSM::VelModifier(), _field(hfPtr) { + } + + //////////////////////////////////////////////////////////////// + + BFSM::VelModifier* HeightFieldModifier::copy() const{ + return new HeightFieldModifier(_field); + }; + + //////////////////////////////////////////////////////////////// + + void HeightFieldModifier::adaptPrefVelocity(const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ){ + Vector2 pref = pVel.getPreferred(); + // This code is derived from fsm Hacks + + // modify direction + Vector3 norm = _field->getNormalAt( agent->_pos._x, agent->_pos._y ); + Vector2 grad( norm._x, norm._z ); + Vector2 newDir = pref + ( _turnWeight * grad ); + newDir.normalize(); + pVel.setSingle( newDir ); + + // modify speed + float len = abs(grad); + float dp = (grad / len) * pref; + //marginal speedup, but large slow down + dp *= ( dp > 0.f ) ? _downHillScale : _upHillScale; + float inSpeed = pVel.getSpeed(); + float modSpeed = inSpeed * (1.f + (len * dp)); + pVel.setSpeed( modSpeed ); + } + + + ///////////////////////////////////////////////////////////////////// + // Implementation of FormationModFactory + ///////////////////////////////////////////////////////////////////// + + HeightFieldModifierFactory::HeightFieldModifierFactory(): BFSM::VelModFactory() { + _fileNameID = _attrSet.addStringAttribute( "file_name", true /*required*/ ); + _turnID = _attrSet.addFloatAttribute( "dir_weight", false /*required*/, 1.2f ); + _uphillID = _attrSet.addFloatAttribute( "up_hill_scale", false /*required*/, 1.f ); + _downhillID = _attrSet.addFloatAttribute( "down_hill_scale", false /*required*/, 0.2f ); + } + + ///////////////////////////////////////////////////////////////////// + + bool HeightFieldModifierFactory::setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const { + HeightFieldModifier * hfm = dynamic_cast< HeightFieldModifier * >( modifier ); + assert( hfm != 0x0 && "Trying to set attributes of a height field velocity modifier on an incompatible object" ); + + if ( ! BFSM::VelModFactory::setFromXML( hfm, node, behaveFldr ) ) return false; + + // get the file name + std::string fName; + std::string path = os::path::join( 2, behaveFldr.c_str(), _attrSet.getString( _fileNameID ).c_str() ); + os::path::absPath( path, fName ); + + // height field + HeightFieldPtr hfPtr; + try { + hfPtr = loadHeightField( fName ); + } catch ( ResourceException ) { + logger << Logger::ERR_MSG << "Couldn't instantiate the height field elevation referenced on line " << node->Row() << "."; + return false; + } + hfm->setHeightField( hfPtr ); + hfm->_turnWeight = _attrSet.getFloat( _turnID ); + hfm->_upHillScale = _attrSet.getFloat( _uphillID ); + hfm->_downHillScale = _attrSet.getFloat( _downhillID ); + + return true; + } + +} //namespace Terrain + diff --git a/src/Plugins/Terrain/VelModHeightField.h b/src/Plugins/Terrain/VelModHeightField.h new file mode 100644 index 00000000..ec21ee45 --- /dev/null +++ b/src/Plugins/Terrain/VelModHeightField.h @@ -0,0 +1,247 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file VelModHeightField.h + * @brief definition of a VelocityModifier to push agents along the gradient of a heightField + */ +#ifndef __VELMOD_HEIGHT_FIELD_H__ +#define __VELMOD_HEIGHT_FIELD_H__ + +// Resources +#include "HeightField.h" + +// Menge Base +#include "VelocityModifiers/VelModifier.h" +#include "VelocityModifiers/VelModifierFactory.h" + +//forward declarations +class TiXmlElement; + +namespace Menge { + namespace Agents { + class BaseAgent; + } +} + +using namespace Menge; + +namespace Terrain { + + //forward declare Factory + class HeightFieldModifierFactory; + + /*! + * @brief Modify the preferred velocity based on a height field. + * + * Agents preferred velocities can be sped up, slowed, and turned based on their attempt + * to traverse a heightfield. The gradient of the height field is used to determine the + * new preferred velocity. + * + * Direction is determined by a re-normalized, weighted sum of the gradient with the input + * preferred direction. + * + * The resultant speed is a scaled factor of the input speed with the steepness of the gradient. + * Uphill and downhill speed changes are controlled separately -- gradients which lie perpindicular + * to the input preferred direction will cause a direction change, but no speed change. + * + * The output preferred velocity becomes a single velocity (instead of an arc). + * If the input preferred velocity spanned an arc, it will be collapsed to a single direction. + */ + class EXPORT_API HeightFieldModifier : public BFSM::VelModifier { + public: + + /*! + * @brief Default constructor + */ + HeightFieldModifier(); + + /*! + * @brief Constructor + * + * @param hfPtr A pointer to a height-field resource. + */ + HeightFieldModifier( HeightFieldPtr hfPtr ); + + /*! + * @brief Sets the height field for this velocity modifier object to use. + * + * @param hfPtr A managed pointer to the height field. + */ + void setHeightField( HeightFieldPtr hfPtr ) { _field = hfPtr; } + + /*! + * + * @brief Copy method for this velocity modifier + * + */ + BFSM::VelModifier* copy() const; + + /*! + * @brief adapt preferred velocity by pushing it away from the heightfield gradient + * + * @param agent The agent for which to modify preferred vel + * @param pVel The agent's current preferred velocity (having potentially been modified) + * + */ + void adaptPrefVelocity(const Agents::BaseAgent * agent, Agents::PrefVelocity & pVel ); + + /* + * identify the factory helper + */ + friend class HeightFieldModifierFactory; + + protected: + + /*! + * @brief The height field used to query elevation and gradient + */ + HeightFieldPtr _field; + + /*! + * @brief The weighting factor for how the gradient effects direction. + */ + float _turnWeight; + + /*! + * @brief The uphill scale factor. + */ + float _upHillScale; + + /*! + * @brief The downhill scale factor. + */ + float _downHillScale; + + }; + + + ////////////////////////////////////////////////////////////////////////////// + + /*! + * @brief Factory for the HeightFieldModifier. + */ + class EXPORT_API HeightFieldModifierFactory : public BFSM::VelModFactory { + public: + /*! + * + * @brief Constructor. + * + */ + HeightFieldModifierFactory(); + + /*! + * @brief The name of the modifier + * + * The modifier's name must be unique among all registered modifier. + * Each modifier factory must override this function. + * + * @returns A string containing the unique modifier name. + */ + virtual const char * name() const { return "height_field"; } + + /*! + * @brief A description of the modifier + * + * Each modifier factory must override this function. + * + * @returns A string containing the modifier description. + */ + virtual const char * description() const { + return "Pushes the agent's preferred velocity away from the gradient of a height field"; + }; + + protected: + /*! + * @brief Create an instance of this class's modifier. + * + * All modifierFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding modifier type. The various field values + * of the instance will be set in a subsequent call to modifierFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated modifier class. + */ + BFSM::VelModifier * instance() const { return new HeightFieldModifier(); } + + /*! + * @brief Given a pointer to an modifier instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this modifier's type. + * (i.e. modifierFactory::thisFactory has already been called and returned true.) + * If sub-classes of modifierFactory introduce *new* modifier parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param modifier A pointer to the modifier whose attributes are to be set. + * @param node The XML node containing the modifier attributes. + * @param behaveFldr The path to the behavior file. If the modifier references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( BFSM::VelModifier * modifier, TiXmlElement * node, const std::string & behaveFldr ) const; + + /*! + * @brief The identifier for the "file_name" string attribute. + */ + size_t _fileNameID; + + /*! + * @brief The identifier for the "dir_weight" float attribute. + */ + size_t _turnID; + + /*! + * @brief The identifier for the "up_hill_scale" float attribute. + */ + size_t _uphillID; + + /*! + * @brief The identifier for the "down_hill_scale" float attribute. + */ + size_t _downhillID; + + + + + }; +}; +#endif diff --git a/src/Plugins/aircraft/Aircraft.cpp b/src/Plugins/aircraft/Aircraft.cpp new file mode 100644 index 00000000..214f6b64 --- /dev/null +++ b/src/Plugins/aircraft/Aircraft.cpp @@ -0,0 +1,80 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file Aircraft.cpp + * @brief Plugin for aircraft loading and unloading. + */ + +#include "AircraftConfig.h" +#include "AircraftAction.h" +#include "AircraftTransition.h" +#include "PluginEngine.h" + +/*! + * @brief Retrieves the name of the plug-in. + * + * @returns The name of the plug in. + */ +extern "C" EXPORT_API const char * getName() { + return "Aircraft_utils"; +} + +/*! + * @brief Description of the plug-in. + * + * @returns A description of the plugin. + */ +extern "C" EXPORT_API const char * getDescription() { + return "Utilties for simulating aircraft loading and unloading " \ + "including the following:\n"\ + "\tAction \"set_xproperty\" - which sets properties according to the " \ + "agent's position along the x-axis\n"\ + "\tCondition \"clear_AABB\" - Transition into a state according to whether or not an AABB is clear "; +} + +/*! + * @brief Registers the plug-in with the PluginEngine + * + * @param engine A pointer to the plugin engine. + */ +extern "C" EXPORT_API void registerPlugin( PluginEngine * engine ) { + engine->registerActionFactory( new Aircraft::PropertyXActFactory() ); + engine->registerConditionFactory(new Aircraft::ClearAABBCondFactory()); +} + diff --git a/src/Plugins/aircraft/AircraftAction.cpp b/src/Plugins/aircraft/AircraftAction.cpp new file mode 100644 index 00000000..e36fe020 --- /dev/null +++ b/src/Plugins/aircraft/AircraftAction.cpp @@ -0,0 +1,190 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +#include "AircraftAction.h" +#include "Actions/PropertyAction.h" +#include "BaseAgent.h" +#include "SimulatorInterface.h" +#include "FSM.h" +#include "BFSM/GoalSet.h" +#include <iostream> + +namespace Aircraft { + + ///////////////////////////////////////////////////////////////////// + // Implementation of PropertyXAction + ///////////////////////////////////////////////////////////////////// + + PropertyXAction::PropertyXAction():Action(),_xOrigin(0.f),_originValue(0.f),_scale(0.f),_property(BFSM::NO_PROPERTY),_originalMap() { + } + + ///////////////////////////////////////////////////////////////////// + + PropertyXAction::~PropertyXAction() { + _originalMap.clear(); + } + + ///////////////////////////////////////////////////////////////////// + + void PropertyXAction::onEnter( Agents::BaseAgent * agent ) { + float value = ( agent->_pos.x() - _xOrigin ) * _scale + _originValue; + _lock.lock(); + switch ( _property ) { + case BFSM::MAX_SPEED: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_maxSpeed; + agent->_maxSpeed = value; + break; + case BFSM::MAX_ACCEL: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_maxAccel; + agent->_maxAccel = value; + break; + case BFSM::PREF_SPEED: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_prefSpeed; + agent->_prefSpeed = value; + break; + case BFSM::MAX_ANGLE_VEL: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_maxAngVel; + agent->_maxAngVel = value; + break; + case BFSM::NEIGHBOR_DIST: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_neighborDist; + agent->_neighborDist = value; + break; + case BFSM::PRIORITY: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_priority; + agent->_priority = value; + break; + case BFSM::RADIUS: + if ( _undoOnExit ) _originalMap[ agent->_id ] = agent->_radius; + agent->_radius = value; + break; + } + _lock.release(); + } + + ///////////////////////////////////////////////////////////////////// + + void PropertyXAction::leaveAction( Agents::BaseAgent * agent ) { + _lock.lock(); + std::map< size_t, float >::iterator itr = _originalMap.find( agent->_id ); + assert( itr != _originalMap.end() && "An agent is exiting a state that it apparently never entered" ); + float value = itr->second; + _originalMap.erase( itr ); + _lock.release(); + switch ( _property ) { + case BFSM::MAX_SPEED: + agent->_maxSpeed = value; + break; + case BFSM::MAX_ACCEL: + agent->_maxAccel = value; + break; + case BFSM::PREF_SPEED: + agent->_prefSpeed = value; + break; + case BFSM::MAX_ANGLE_VEL: + agent->_maxAngVel = value; + break; + case BFSM::NEIGHBOR_DIST: + agent->_neighborDist = value; + break; + case BFSM::PRIORITY: + agent->_priority = value; + break; + case BFSM::RADIUS: + agent->_radius = value; + break; + } + } + + ///////////////////////////////////////////////////////////////////// + // Implementation of PropertyXActFactory + ///////////////////////////////////////////////////////////////////// + + bool PropertyXActFactory::setFromXML( BFSM::Action * action, TiXmlElement * node, const std::string & behaveFldr ) const { + PropertyXAction * pAction = dynamic_cast< PropertyXAction * >( action ); + assert( pAction != 0x0 && "Trying to set property action properties on an incompatible object" ); + if ( ! BFSM::ActionFactory::setFromXML( action, node, behaveFldr ) ) { + return false; + } + // set the target property + const char * pName = node->Attribute( "property" ); + if ( ! pName ) { + logger << Logger::ERR_MSG << "The property action defined on line " << node->Row() << " did not define the \"property\" attribute\n"; + return false; + } + pAction->_property = Menge::parsePropertyName( pName ); + if ( pAction->_property == BFSM::NO_PROPERTY ) { + logger << Logger::ERR_MSG << "The set property x action defined online " << node->Row() << " specified an invalid value for the \"property\" attribute\n"; + return false; + } + + double d; + // Get the x-origin value + if ( node->Attribute( "origin", &d ) ) { + pAction->_xOrigin = (float) d; + } else { + logger << Logger::WARN_MSG << "The set property x action defined on line " << node->Row() << " did not define the \"origin\" attribute. Using the default value 0.0\n"; + pAction->_xOrigin = 0.f; + } + + // Get the origin value + if ( node->Attribute( "origin_value", &d ) ) { + pAction->_originValue = (float) d; + } else { + logger << Logger::WARN_MSG << "The set property x action defined on line " << node->Row() << " did not define the \"origin_value\" attribute. Using the default value 0.0\n"; + pAction->_originValue = 0.f; + } + + // Get the scale value + if ( node->Attribute( "scale", &d ) ) { + pAction->_scale = (float) d; + } else { + logger << Logger::WARN_MSG << "The set property x action defined on line " << node->Row() << " did not define the \"scale\" attribute. Using the default value 0.0\n"; + pAction->_scale = 0.f; + } + + + return true; + } + + + + + + +} // namespace Aircraft diff --git a/src/Plugins/aircraft/AircraftAction.h b/src/Plugins/aircraft/AircraftAction.h new file mode 100644 index 00000000..7719b5aa --- /dev/null +++ b/src/Plugins/aircraft/AircraftAction.h @@ -0,0 +1,203 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AircraftAction.h + * @brief Definition of actions used in Aircraft + * loading and unloading. + */ +#ifndef __Aircraft_ACTION_H__ +#define __Aircraft_ACTION_H__ + +#include "AircraftConfig.h" +#include "Actions/Action.h" +#include "Actions/ActionFactory.h" +#include "SimpleLock.h" +#include "FSMEnumeration.h" +#include <map> + +using namespace Menge; + +//forward declaration +class TiXmlElement; + +/*! + * @namespace Aircraft + * @brief The namespace containing Menge elements required for simulating + * aircraft loading and unloading. + */ +namespace Aircraft { + // forward declaration + class SetPropertyXActFactory; + + /*! + * @brief An action that sets agent properties based on the + * agent's position along the x-axis. + */ + class EXPORT_API PropertyXAction : public BFSM::Action { + public: + /*! + * @brief Constructor + */ + PropertyXAction(); + + /*! + * @brief Virtual destructor. + */ + ~PropertyXAction(); + + /*! + * @brief Upon entering the state, this is called -- it is the main work + * of the action. + * + * @param agent The agent to act on. + */ + void onEnter( Agents::BaseAgent * agent ); + + friend class PropertyXActFactory; + + protected: + + /*! + * @brief The work to do upon state exit. + * + * @param agent The agent to act on. + */ + void leaveAction( Agents::BaseAgent * agent ); + + protected: + /*! + * @brief The x-position at which the value is set to + * _originValue; + */ + float _xOrigin; + + /*! + * @brief The value for the property at _xOrigin; + */ + float _originValue; + + /*! + * @brief The rate of change to the property for each unit + * displacement along the x-axis. (Essentially, this + * is the slope of the line.) + */ + float _scale; + + /*! + * @brief The property to operate on. + */ + BFSM::PropertyOperand _property; + + /*! + * @brief A mapping from agent id to the agent's property + * value before the action was applied. + */ + std::map< size_t, float > _originalMap; + + /*! + * @brief Lock to protect _originalMap. + */ + SimpleLock _lock; + }; + + /*! + * @brief Factory for instantiating PropertyXAction instances. + */ + class EXPORT_API PropertyXActFactory : public BFSM::ActionFactory { + public: + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + virtual const char * name() const { return "set_xproperty"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + virtual const char * description() const { + return "Sets an agent property's value from a simple linear equation dependent on the agent's x-position."; + }; + + protected: + /*! + * @brief Create an instance of this class's action. + * + * All ActionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding action type. The various field values + * of the instance will be set in a subsequent call to ActionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + BFSM::Action * instance() const { return new PropertyXAction(); } + + /*! + * @brief Given a pointer to an Action instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Action's type. + * (i.e. ActionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ActionFactory introduce *new* Action parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param action A pointer to the action whose attributes are to be set. + * @param node The XML node containing the action attributes. + * @param behaveFldr The path to the behavior file. If the action references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( BFSM::Action * action, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + + + +} // namespace Aircraft + +#endif // __Aircraft_ACTION_H__ diff --git a/src/Plugins/aircraft/AircraftConfig.h b/src/Plugins/aircraft/AircraftConfig.h new file mode 100644 index 00000000..c0d6dd97 --- /dev/null +++ b/src/Plugins/aircraft/AircraftConfig.h @@ -0,0 +1,86 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AircraftConfig.h + * @brief Configures the shared library aspect of the includes. + */ + +#ifndef __AIRCRAFT_CONFIG_H__ +#define __AIRCRAFT_CONFIG_H__ + + +// Now set up compiler-dependent export/import symbols + +#if defined(_MSC_VER) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + // We are building the DLL, export the symbols tagged like this + #define EXPORT_API __declspec(dllexport) + #else + // If we are consuming the DLL, import the symbols tagged like this + #define EXPORT_API __declspec(dllimport) + #endif + #endif + +#elif defined(__GNUC__) + + #if defined( STATICLIB ) + #define EXPORT_API + #else + #if defined( EXPORT ) + #define EXPORT_API __attribute__ ((visibility ("default"))) + #else + // If you use -fvisibility=hidden in GCC, exception handling and RTTI + // would break if visibility wasn't set during export _and_ import + // because GCC would immediately forget all type infos encountered. + // See http://gcc.gnu.org/wiki/Visibility + #define EXPORT_API __attribute__ ((visibility ("default"))) + #endif + #endif + +#else + + #error Unknown compiler, please implement shared library macros + +#endif // Compiler-detection + +#endif // __AIRCRAFT_CONFIG_H__ \ No newline at end of file diff --git a/src/Plugins/aircraft/AircraftTransition.cpp b/src/Plugins/aircraft/AircraftTransition.cpp new file mode 100644 index 00000000..8c81adac --- /dev/null +++ b/src/Plugins/aircraft/AircraftTransition.cpp @@ -0,0 +1,161 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AircraftTransition.h + * @brief Definition of transition condition used in aircraft + * loading and unloading. + */ + +#include "AircraftConfig.h" +#include "AircraftTransition.h" +#include "Transitions/ConditionFactory.h" +#include "FSMEnumeration.h" +#include <map> +#include "BaseAgent.h" +#include "Core.h" +#include "SimulatorInterface.h" + +namespace Aircraft { + + ///////////////////////////////////////////////////////////////////////// + // Implementation of ClearAABBCondition + ///////////////////////////////////////////////////////////////////////// + + ClearAABBCondition::ClearAABBCondition( const ClearAABBCondition & cond ): BFSM::Condition(cond), _relative(cond._relative), _agentClass(cond._agentClass), _baseBox(cond._baseBox) { + } + + ///////////////////////////////////////////////////////////////////////// + + ClearAABBCondition::~ClearAABBCondition() { + + } + + ///////////////////////////////////////////////////////////////////////// + + bool ClearAABBCondition::conditionMet( Agents::BaseAgent * agent, const BFSM::Goal * goal ){ + // Determine if the agent's AABB is clear of the target class of agents + //std::cout << "ClearAABBCondition on agent " << agent->_id << "\n"; + Vector2 offset(0.f,0.f); + if ( _relative ) { + //std::cout << "\tRelative to position: " << agent->_pos << "\n"; + offset.set( agent->_pos ); + } + AABBShape activeBox( _baseBox, offset ); + + //TODO: OPTIMIZE THIS + const size_t NUM_AGENT = Menge::SIMULATOR->getNumAgents(); + for ( size_t i = 0; i < NUM_AGENT; ++i ) { + const Agents::BaseAgent * testAgent = Menge::SIMULATOR->getAgent( i ); + //if this agent is in my box + if ( testAgent->_id != agent->_id && + ( _agentClass == -1 || _agentClass == testAgent->_class ) + ){ + if ( activeBox.containsPoint(testAgent->_pos ) ) { + return false; + } + } + } + + return true; + }; + + ///////////////////////////////////////////////////////////////////////// + + BFSM::Condition * ClearAABBCondition::copy() { + return new ClearAABBCondition( *this ); + } + + ///////////////////////////////////////////////////////////////////////// + + void ClearAABBCondition::setParams(float xMin, float xMax, float yMin, float yMax, bool relative, int agentClass){ + //set the properties of this box + _relative = relative; + _agentClass = (size_t)agentClass; + _baseBox.set( Vector2( xMin, yMin ), Vector2( xMax, yMax ) ); + }; + + /////////////////////////////////////////////////////////////////////////// + // Implementation of ClearAABBCondFactory + /////////////////////////////////////////////////////////////////////////// + + bool ClearAABBCondFactory::setFromXML( BFSM::Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const { + ClearAABBCondition * cond = dynamic_cast< ClearAABBCondition * >( condition ); + assert( cond != 0x0 && "Trying to set the properties of a ClearAABB condition on an incompatible object" ); + + if ( !BFSM::ConditionFactory::setFromXML( cond, node, behaveFldr ) ) { + return false; + } + // dimensions + bool valid = true; + double xMin, xMax, yMin, yMax; + int relative, agentClass; + + // determine if it is active inside or outside + if ( ! node->Attribute( "relative", &relative ) ) { + logger << Logger::ERR_MSG << "The clear_AABB condition on line " << node->Row() << " is missing the \"relative\" attribute."; + return false; + } + if ( ! node->Attribute( "min_x", &xMin ) ) { + logger << Logger::ERR_MSG << "The clear_AABB condition on line " << node->Row() << " is missing the \"min_x\" property."; + valid = false; + } + if ( ! node->Attribute( "max_x", &xMax ) ) { + logger << Logger::ERR_MSG << "The clear_AABB condition on line " << node->Row() << " is missing the \"max_x\" property."; + valid = false; + } + if ( ! node->Attribute( "min_y", &yMin ) ) { + logger << Logger::ERR_MSG << "The clear_AABB condition on line " << node->Row() << " is missing the \"min_y\" property."; + valid = false; + } + if ( ! node->Attribute( "max_y", &yMax ) ) { + logger << Logger::ERR_MSG << "The clear_AABB condition on line " << node->Row() << " is missing the \"max_y\" property."; + valid = false; + } + if (!node->Attribute( "agent_class", &agentClass ) ) { + logger << Logger::WARN_MSG << "The clear_AABB condition on line " << node->Row() << " did not define \"agentClass\" property. Using -1."; + agentClass = -1; + } + if ( ! valid ) return false; + + cond->setParams( (float)xMin, (float)xMax, (float)yMin, (float)yMax, relative != 0, agentClass ); + + return true; + } +} // namespace Aircraft + diff --git a/src/Plugins/aircraft/AircraftTransition.h b/src/Plugins/aircraft/AircraftTransition.h new file mode 100644 index 00000000..5e5d669a --- /dev/null +++ b/src/Plugins/aircraft/AircraftTransition.h @@ -0,0 +1,204 @@ +/* + +License + +Menge +Copyright © and trademark ™ 2012-14 University of North Carolina at Chapel Hill. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its documentation +for educational, research, and non-profit purposes, without fee, and without a +written agreement is hereby granted, provided that the above copyright notice, +this paragraph, and the following four paragraphs appear in all copies. + +This software program and documentation are copyrighted by the University of North +Carolina at Chapel Hill. The software program and documentation are supplied "as is," +without any accompanying services from the University of North Carolina at Chapel +Hill or the authors. The University of North Carolina at Chapel Hill and the +authors do not warrant that the operation of the program will be uninterrupted +or error-free. The end-user understands that the program was developed for research +purposes and is advised not to rely exclusively on the program for any reason. + +IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS +BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY +DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY STATUTORY WARRANTY +OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +Any questions or comments should be sent to the authors {menge,geom}@cs.unc.edu + +*/ + +/*! + * @file AircraftTransition.h + * @brief Definition of actions used in aircraft + * loading and unloading. + */ +#ifndef __AIRLINE_TRANSITION_H__ +#define __AIRLINE_TRANSITION_H__ + +#include "AircraftConfig.h" +#include "Transitions/Condition.h" +#include "Transitions/ConditionFactory.h" +#include "FSMEnumeration.h" +#include "Math/Geometry2D.h" +#include <map> + +using namespace Menge; + +//forward declaration +class TiXmlElement; + +namespace Aircraft { + // forward declaration + class ClearAABBCondFactory; + + /*! + * @brief An action that sets agent properties based on the + * agent's position along the x-axis. + */ + class EXPORT_API ClearAABBCondition : public BFSM::Condition { + public: + /*! + * @brief Constructor + */ + ClearAABBCondition(): BFSM::Condition(), _relative(false), _agentClass(-1), _baseBox(){} // -1 is maximum agent class value + + /*! + * @brief Copy constructor + * + * @param cond The condition to copy from. + */ + ClearAABBCondition( const ClearAABBCondition & cond ); + + protected: + /*! + * @brief Virtual destructor. + */ + virtual ~ClearAABBCondition(); + + public: + /*! + * @brief The AutoCondition is always met -- it is a tautology. + * + * @param agent The agent to test the transition for. + * @param goal The agent's goal (although this may be ignored). + * @returns True if the condition has been met, false otherwise. + */ + virtual bool conditionMet( Agents::BaseAgent * agent, const BFSM::Goal * goal ); + + /*! + * @brief Create a copy of this condition. + * + * It is the responsibility of the caller to delete the object. + * + * @returns: A "deep copy" of this condition - such that there is no shared + * objects between this and its copy. + */ + virtual BFSM::Condition * copy(); + + friend class ClearAABBCondFactory; + + /*! + * @brief Sets the dimensions of the bounding box. + * + * @param xMin The minimum point on the AABB along the x-axis. + * @param xMax The maximum point on the AABB along the x-axis. + * @param yMin The minimum point on the AABB along the y-axis. + * @param yMax The maximum point on the AABB along the y-axis. + * @param relative Specifies if the clear box is relative (true) to the + * agents *current* position, or absolute in the world. + * @param agentClass The class of the agents which are tested. If -1 + * all agents are considered. + */ + void setParams(float xMin, float xMax, float yMin, float yMax, bool relative, int agentClass); + + protected: + /*! + * @brief Indicates whether the box is defined relative to the agent's position (true) or not (false). + */ + bool _relative; + + /*! + * @brief The agent class this transition operates on. + * If -1, all agent classes are tested. + */ + size_t _agentClass; + + /*! + * @brief The definition of the underlying AABB. + */ + AABBShape _baseBox; + }; + + /*! + * @brief The factory for creating the ClearAABBCondition + */ + class EXPORT_API ClearAABBCondFactory : public BFSM::ConditionFactory { + public: + /*! + * @brief The name of the action. + * + * The action's name must be unique among all registered actions. + * Each action factory must override this function. + * + * @returns A string containing the unique action name. + */ + const char * name() const { return "clear_AABB"; } + + /*! + * @brief A description of the action. + * + * Each action factory must override this function. + * + * @returns A string containing the action description. + */ + const char * description() const { + return "The clear axis-aligned bounding box (AABB) condition. It becomes active when no agents are in a box "\ + "defined in either an absolute position, or relative to the agent."; + } + + protected: + /*! + * @brief Create an instance of this class's condition. + * + * All ConditionFactory sub-classes must override this by creating (on the heap) + * a new instance of its corresponding condition type. The various field values + * of the instance will be set in a subsequent call to ConditionFactory::setFromXML. + * The caller of this function takes ownership of the memory. + * + * @returns A pointer to a newly instantiated Action class. + */ + ClearAABBCondition * instance() const { return new ClearAABBCondition(); } + + /*! + * @brief Given a pointer to an Condition instance, sets the appropriate fields + * from the provided XML node. + * + * It is assumed that the value of the `type` attribute is this Tarnsitions's type. + * (i.e. ConditionFactory::thisFactory has already been called and returned true.) + * If sub-classes of ConditionFactory introduce *new* Condition parameters, then the + * sub-class should override this method but explicitly call the parent class's + * version. + * + * @param condition A pointer to the condition whose attributes are to be set. + * @param node The XML node containing the condition attributes. + * @param behaveFldr The path to the behavior file. If the condition references + * resources in the file system, it should be defined relative + * to the behavior file location. This is the folder containing + * that path. + * @returns A boolean reporting success (true) or failure (false). + */ + virtual bool setFromXML( BFSM::Condition * condition, TiXmlElement * node, const std::string & behaveFldr ) const; + }; + +} // namespace Aircraft + +#endif // __AIRCRAFT_ACTION_H__